Merge. Refresh from viewer-release.

Thu, 18 Jul 2013 18:43:58 -0400

author
Monty Brandenberg <monty@lindenlab.com>
date
Thu, 18 Jul 2013 18:43:58 -0400
changeset 40696
589d6dbc8c66
parent 40695
916573da16a0
parent 37307
421c20423df9
child 40697
1909fb80b76f

Merge. Refresh from viewer-release.

indra/lib/python/indra/util/llversion.py file | annotate | diff | revisions
indra/llcommon/CMakeLists.txt file | annotate | diff | revisions
indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl file | annotate | diff | revisions
indra/newview/llmeshrepository.cpp file | annotate | diff | revisions
indra/newview/lltexturefetch.cpp file | annotate | diff | revisions
indra/newview/lltexturefetch.h file | annotate | diff | revisions
indra/newview/llviewerregion.cpp file | annotate | diff | revisions
     1.1 --- a/.hgtags	Thu Jul 18 15:14:55 2013 -0400
     1.2 +++ b/.hgtags	Thu Jul 18 18:43:58 2013 -0400
     1.3 @@ -72,35 +72,35 @@
     1.4  461c8c65b5c799ddfe365422f9be9c0095d91e7d 2.6.0-beta1-tip
     1.5  9e4641f4a7870c0f565a25a2971368d5a29516a1 2.6.0-beta2
     1.6  9e4641f4a7870c0f565a25a2971368d5a29516a1 DRTVWR-41_2.6.0-beta2
     1.7 +42f32494bac475d0737799346f6831558ae8bf5d 2.6.0-release
     1.8 +42f32494bac475d0737799346f6831558ae8bf5d DRTVWR-39_2.6.0-release
     1.9  c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-beta1
    1.10  c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-start
    1.11  c5bdef3aaa2744626aef3c217ce29e1900d357b3 DRTVWR-43_2.6.1-beta1
    1.12 +c9182ed77d427c759cfacf49a7b71a2e20d522aa 2.6.1-release
    1.13 +c9182ed77d427c759cfacf49a7b71a2e20d522aa DRTVWR-42_2.6.1-release
    1.14  56b2778c743c2a964d82e1caf11084d76a87de2c 2.6.2-start
    1.15  d1203046bb653b763f835b04d184646949d8dd5c 2.6.2-beta1
    1.16  d1203046bb653b763f835b04d184646949d8dd5c DRTVWR-45_2.6.2-beta1
    1.17 -42f32494bac475d0737799346f6831558ae8bf5d 2.6.0-release
    1.18 -42f32494bac475d0737799346f6831558ae8bf5d DRTVWR-39_2.6.0-release
    1.19 -c9182ed77d427c759cfacf49a7b71a2e20d522aa 2.6.1-release
    1.20 -c9182ed77d427c759cfacf49a7b71a2e20d522aa DRTVWR-42_2.6.1-release
    1.21 +214180ad5714ce8392b82bbebcc92f4babd98300 2.6.2-release
    1.22 +214180ad5714ce8392b82bbebcc92f4babd98300 DRTVWR-44_2.6.2-release
    1.23  52b2263ab28f0976c689fd0b76c55a9eb027cdbf end-of-develop.py
    1.24  ec32f1045e7c2644015245df3a9933620aa194b8 2.6.3-start
    1.25  d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc 2.6.3-beta1
    1.26  d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc DRTVWR-47_2.6.3-beta1
    1.27  0630e977504af5ea320c58d33cae4e1ddee793e9 2.6.3-beta2
    1.28  0630e977504af5ea320c58d33cae4e1ddee793e9 DRTVWR-48_2.6.3-beta2
    1.29 +8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release
    1.30 +8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release
    1.31  3178e311da3a8739a85363665006ea3c4610cad4 dons-headless-hackathon-work
    1.32 -214180ad5714ce8392b82bbebcc92f4babd98300 2.6.2-release
    1.33 -214180ad5714ce8392b82bbebcc92f4babd98300 DRTVWR-44_2.6.2-release
    1.34  7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd 2.6.5-beta1
    1.35  7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd DRTVWR-50_2.6.5-beta1
    1.36 -8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release
    1.37 -8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release
    1.38  800cefce8d364ffdd2f383cbecb91294da3ea424 2.6.6-start
    1.39  bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 2.6.6-beta1
    1.40  bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 DRTVWR-52_2.6.6-beta1
    1.41 -5e349dbe9cc84ea5795af8aeb6d473a0af9d4953 2.6.8-start
    1.42  dac76a711da5f1489a01c1fa62ec97d99c25736d 2.6.6-release
    1.43  dac76a711da5f1489a01c1fa62ec97d99c25736d DRTVWR-51_2.6.6-release
    1.44 +5e349dbe9cc84ea5795af8aeb6d473a0af9d4953 2.6.8-start
    1.45  beafa8a9bd1d1b670b7523d865204dc4a4b38eef 2.6.8-beta1
    1.46  beafa8a9bd1d1b670b7523d865204dc4a4b38eef DRTVWR-55_2.6.8-beta1
    1.47  be2000b946f8cb3de5f44b2d419287d4c48ec4eb 2.6.8-release
    1.48 @@ -119,50 +119,50 @@
    1.49  9f79a6ed8fdcd2f3dac33ea6b3236eeb278dccfe 2.7.2-start
    1.50  e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb 2.7.2-beta1
    1.51  e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb DRTVWR-63_2.7.2-beta1
    1.52 -6a3e7e403bd19e45fdfc2fcc716867af3ab80861 2.7.3-start
    1.53  fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.1-release
    1.54  fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.2-release
    1.55  fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-60_2.7.1-release
    1.56  fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-62_2.7.2-release
    1.57 +6a3e7e403bd19e45fdfc2fcc716867af3ab80861 2.7.3-start
    1.58  6af10678de4736222b2c3f7e010e984fb5b327de 2.7.4-start
    1.59  be963a4eef635542f9617d7f5fd22ba48fb71958 2.7.4-beta1
    1.60  be963a4eef635542f9617d7f5fd22ba48fb71958 DRTVWR-67_2.7.4-beta1
    1.61 +057f319dd8eccdf63a54d99686c68cdcb31b6abc 2.7.4-release
    1.62 +057f319dd8eccdf63a54d99686c68cdcb31b6abc DRTVWR-66_2.7.4-release
    1.63  19a498fa62570f352d7d246f17e3c81cc1d82d8b 2.7.5-start
    1.64  09984bfa6cae17e0f72d02b75c1b7393c65eecfc 2.7.5-beta1
    1.65  09984bfa6cae17e0f72d02b75c1b7393c65eecfc DRTVWR-69_2.7.5-beta1
    1.66 +6866d9df6efbd441c66451debd376d21211de39c 2.7.5-release
    1.67 +6866d9df6efbd441c66451debd376d21211de39c DRTVWR-68_2.7.5-release
    1.68  e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-beta1
    1.69  e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-start
    1.70  e1ed60913230dd64269a7f7fc52cbc6004f6d52c DRTVWR-71_2.8.0-beta1
    1.71 -057f319dd8eccdf63a54d99686c68cdcb31b6abc 2.7.4-release
    1.72 -057f319dd8eccdf63a54d99686c68cdcb31b6abc DRTVWR-66_2.7.4-release
    1.73 -6866d9df6efbd441c66451debd376d21211de39c 2.7.5-release
    1.74 -6866d9df6efbd441c66451debd376d21211de39c DRTVWR-68_2.7.5-release
    1.75 +493d9127ee50e84ba08a736a65a23ca86f7a5b01 2.8.0-release
    1.76 +493d9127ee50e84ba08a736a65a23ca86f7a5b01 DRTVWR-70_2.8.0-release
    1.77  502f6a5deca9365ddae57db4f1e30172668e171e 2.8.1-start
    1.78  2c7e459e0c883f8e406b932e41e60097e9ee077e 2.8.1-beta1
    1.79  2c7e459e0c883f8e406b932e41e60097e9ee077e DRTVWR-73_2.8.1-beta1
    1.80 -493d9127ee50e84ba08a736a65a23ca86f7a5b01 2.8.0-release
    1.81 -493d9127ee50e84ba08a736a65a23ca86f7a5b01 DRTVWR-70_2.8.0-release
    1.82 -54bc7823ad4e3a436fef79710f685a7372bbf795 2.8.2-start
    1.83 -ac0f1a132d35c02a58861d37cca75b0429ac9137 2.8.3-start
    1.84  29e93d7e19991011bd12b5748142b11a5dcb4370 2.8.1-release
    1.85  29e93d7e19991011bd12b5748142b11a5dcb4370 DRTVWR-72_2.8.1-release
    1.86  4780e3bd2b3042f91be3426151f28c30d199bb3b 2.8.1-hotfix
    1.87  4780e3bd2b3042f91be3426151f28c30d199bb3b DRTVWR-76_2.8.1-hotfix
    1.88 +54bc7823ad4e3a436fef79710f685a7372bbf795 2.8.2-start
    1.89 +ac0f1a132d35c02a58861d37cca75b0429ac9137 2.8.3-start
    1.90  599677276b227357140dda35bea4a2c18e2e67b5 2.8.3-beta1
    1.91  599677276b227357140dda35bea4a2c18e2e67b5 DRTVWR-75_2.8.3-beta1
    1.92 +fb85792b84bf28428889c4cc966469d92e5dac4c 2.8.3-release
    1.93 +fb85792b84bf28428889c4cc966469d92e5dac4c DRTVWR-74_2.8.3-release
    1.94  6b678ea52f90d5c14181661dcd2546e25bde483e 3.0.0-start
    1.95  b0be6ce3adfef3a014a2389d360539f8a86c5439 3.0.0-beta1
    1.96  b0be6ce3adfef3a014a2389d360539f8a86c5439 DRTVWR-78_3.0.0-beta1
    1.97 -fb85792b84bf28428889c4cc966469d92e5dac4c 2.8.3-release
    1.98 -fb85792b84bf28428889c4cc966469d92e5dac4c DRTVWR-74_2.8.3-release
    1.99 +1778f26b6d0ae762dec3ca37140f66620f2485d9 3.0.0-release
   1.100 +1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-77_3.0.0-release
   1.101  82a2079ffcb57ecb1b3849cb41376b443e1eb912 3.0.1-start
   1.102  364fd63517fbacbbcb9129d096187171ba8c9e48 3.0.1-beta1
   1.103  364fd63517fbacbbcb9129d096187171ba8c9e48 DRTVWR-81_3.0.1-beta1
   1.104  f2412ecd6740803ea9452f1d17fd872e263a0df7 3.0.2-start
   1.105  42784bf50fa01974bada2a1af3892ee09c93fcda 3.0.2-beta1
   1.106  42784bf50fa01974bada2a1af3892ee09c93fcda DRTVWR-83_3.0.2-beta1
   1.107 -1778f26b6d0ae762dec3ca37140f66620f2485d9 3.0.0-release
   1.108 -1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-77_3.0.0-release
   1.109  e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e 3.0.2-beta2
   1.110  e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e DRTVWR-86_3.0.2-beta2
   1.111  b95ddac176ac944efdc85cbee94ac2e1eab44c79 3.0.3-start
   1.112 @@ -170,9 +170,9 @@
   1.113  6694f3f062aa45f64ab391d25a3eb3d5eb1b0871 DRTVWR-85_3.0.3-beta1
   1.114  61aa7974df089e8621fe9a4c69bcdefdb3cc208a 3.0.3-beta2
   1.115  61aa7974df089e8621fe9a4c69bcdefdb3cc208a DRTVWR-89_3.0.3-beta2
   1.116 -586907287be581817b2422b5137971b22d54ea48 3.0.4-start
   1.117  0496d2f74043cf4e6058e76ac3db03d44cff42ce 3.0.3-release
   1.118  0496d2f74043cf4e6058e76ac3db03d44cff42ce DRTVWR-84_3.0.3-release
   1.119 +586907287be581817b2422b5137971b22d54ea48 3.0.4-start
   1.120  92a3aa04775438226399b19deee12ac3b5a62838 3.0.5-start
   1.121  c7282e59f374ee904bd793c3c444455e3399b0c5 3.1.0-start
   1.122  2657fa785bbfac115852c41bd0adaff74c2ad5da 3.1.0-beta1
   1.123 @@ -193,11 +193,11 @@
   1.124  c4911ec8cd81e676dfd2af438b3e065407a94a7a 3.2.1-start
   1.125  9e390d76807fa70d356b8716fb83b8ce42a629ef 3.2.1-beta1
   1.126  9e390d76807fa70d356b8716fb83b8ce42a629ef DRTVWR-100_3.2.1-beta1
   1.127 +a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release
   1.128 +a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release
   1.129  40b46edba007d15d0059c80864b708b99c1da368 3.2.2-start
   1.130  523df3e67378541498d516d52af4402176a26bac 3.2.2-beta1
   1.131  523df3e67378541498d516d52af4402176a26bac DRTVWR-102_3.2.2-beta1
   1.132 -a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release
   1.133 -a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release
   1.134  80f3e30d8aa4d8f674a48bd742aaa6d8e9eae0b5 3.2.3-start
   1.135  3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-beta1
   1.136  3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-start
   1.137 @@ -279,6 +279,10 @@
   1.138  9cd174d3a54d93d409a7c346a15b8bfb40fc58f4 DRTVWR-184
   1.139  ab2ffc547c8a8950ff187c4f6c95e5334fab597b 3.3.4-beta5
   1.140  28e100d0379a2b0710c57647a28fc5239d3d7b99 3.3.4-release
   1.141 +6dfb0fba782c9233dd95f24ec48146db0d3f210b DRTVWR-199
   1.142 +7c9102fb998885621919f2474a002c35b583539b 3.3.4-release2
   1.143 +8c9085066c78ed5f6c9379dc054c82a6fcdb1851 DRTVWR-207
   1.144 +351eea5f9dc192fc5ddea3b02958de97677a0a12 3.3.4-release3
   1.145  005dfe5c4c377207d065fb27858d2eb0b53b143a DRTVWR-167
   1.146  888768f162d2c0a8de1dcc5fb9a08bd8bd120a6b DRTVWR-175
   1.147  a8b3eca451a9eaab59987efb0ab1c4217e3f2dcc DRTVWR-182
   1.148 @@ -294,13 +298,9 @@
   1.149  b1dbb1a83f48f93f6f878cff9e52d2cb635e145c 3.4.0-beta2
   1.150  37402e2b19af970d51b0a814d79892cc5647532b DRTVWR-200
   1.151  182a9bf30e81070361bb020a78003b1cf398e79c 3.4.0-beta3
   1.152 -6dfb0fba782c9233dd95f24ec48146db0d3f210b DRTVWR-199
   1.153 -7c9102fb998885621919f2474a002c35b583539b 3.3.4-release2
   1.154  7649a3dff5ec22d3727377e5f02efd0f421e4cb5 DRTVWR-201
   1.155  84fb70dfe3444e75a44fb4bee43e2fc8221cebdd 3.4.0-beta4
   1.156  573e863be2f26d3687161def4b9fea9b7038dda8 3.4.0-beta5
   1.157 -8c9085066c78ed5f6c9379dc054c82a6fcdb1851 DRTVWR-207
   1.158 -351eea5f9dc192fc5ddea3b02958de97677a0a12 3.3.4-release3
   1.159  af7b28e75bd5a629cd9e0dc46fb3f1757626f493 DRTVWR-212
   1.160  015012c2b740ccdec8a8c3d6e5f898449ecfe0b8 DRTVWR-213
   1.161  62b07aa81b1957897c3846292bb9412977b0af6c 3.3.4-beta6
   1.162 @@ -457,3 +457,8 @@
   1.163  9013c07bfe1c51107233f1924dccdcc5057dd909 3.5.2-beta6
   1.164  9b1b6f33aa5394b27bb652b31b5cb81ef6060370 3.5.2-release
   1.165  a277b841729f2a62ba1e34acacc964bc13c1ad6f 3.5.3-release
   1.166 +fb1630153bac5552046ea914af3f14deabc1def8 3.6.0-materials-beta1
   1.167 +69429d81ae4dd321eda2607901ef0a0fde71b54c 3.6.0-release
   1.168 +69429d81ae4dd321eda2607901ef0a0fde71b54c 3.6.0-release
   1.169 +0a56f33ad6aa112032b14a41dad759ad377bdde9 3.6.0-release
   1.170 +75cf8e855ae1af6895a35da475314c2b5acf1850 3.6.1-release
     2.1 --- a/BuildParams	Thu Jul 18 15:14:55 2013 -0400
     2.2 +++ b/BuildParams	Thu Jul 18 18:43:58 2013 -0400
     2.3 @@ -60,6 +60,7 @@
     2.4  viewer-release.build_viewer_update_version_manager = true
     2.5  viewer-release.codeticket_add_context = false
     2.6  
     2.7 +
     2.8  # ========================================
     2.9  # mesh-development
    2.10  # ========================================
    2.11 @@ -122,6 +123,14 @@
    2.12  viewer-pathfinding.build_viewer_update_version_manager = false
    2.13  
    2.14  # ========================================
    2.15 +# viewer-materials
    2.16 +# ========================================
    2.17 +
    2.18 +viewer-materials.viewer_channel = "Second Life Beta Materials"
    2.19 +viewer-materials.build_debug_release_separately = true
    2.20 +viewer-materials.build_CYGWIN_Debug = false
    2.21 +viewer-materials.build_viewer_update_version_manager = false
    2.22 +
    2.23  # viewer-chui
    2.24  #
    2.25  # ========================================
    2.26 @@ -189,3 +198,5 @@
    2.27  
    2.28  
    2.29  # eof
    2.30 +
    2.31 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/NORSPEC-207.patch	Thu Jul 18 18:43:58 2013 -0400
     3.3 @@ -0,0 +1,164 @@
     3.4 +diff -r fe4bab01522e indra/llprimitive/llrendermaterialtable.cpp
     3.5 +--- a/indra/llprimitive/llrendermaterialtable.cpp	Wed May 15 17:57:21 2013 +0000
     3.6 ++++ b/indra/llprimitive/llrendermaterialtable.cpp	Wed May 22 14:23:04 2013 -0700
     3.7 +@@ -184,6 +184,44 @@
     3.8 + 	}
     3.9 + }
    3.10 + 
    3.11 ++// 'v' is an integer value for 100ths of radians (don't ask...)
    3.12 ++//
    3.13 ++void LLRenderMaterialEntry::LLRenderMaterial::setSpecularMapRotation(S32 v) const
    3.14 ++{
    3.15 ++	// Store the fact that we're using the new rotation rep
    3.16 ++	//
    3.17 ++	m_flags |= kNewSpecularMapRotation;
    3.18 ++
    3.19 ++	// Store 'sign bit' in our m_flags
    3.20 ++	//
    3.21 ++	m_flags &= ~kSpecularMapRotationNegative;
    3.22 ++	m_flags |= (specularMapRotation < 0) ? kSpecularMapRotationNegative : 0;
    3.23 ++
    3.24 ++	specularRotation = abs(specularRotation);
    3.25 ++	specularRotation = llmin(specularRotation, MAX_MATERIAL_MAP_ROTATION);
    3.26 ++
    3.27 ++	m_specularRotation = (U16)(abs(specularMapRotation));
    3.28 ++}
    3.29 ++
    3.30 ++// 'v' is an integer value for 100ths of radians (don't ask...)
    3.31 ++//
    3.32 ++void LLRenderMaterialEntry::LLRenderMaterial::setNormalMapRotation(S32 v) const
    3.33 ++{
    3.34 ++
    3.35 ++	// Store the fact that we're using the new rep for this material
    3.36 ++	//
    3.37 ++	m_flags |= kNewNormalMapRotation;
    3.38 ++
    3.39 ++	// Store 'sign bit' in our m_flags
    3.40 ++	//
    3.41 ++	m_flags &= ~kNormalMapRotationNegative;
    3.42 ++	m_flags |= (normalMapRotation < 0) ? kNormalMapRotationNegative : 0;
    3.43 ++
    3.44 ++	normalRotation = abs(normalRotation);
    3.45 ++	normalRotation = llmin(normalRotation, MAX_MATERIAL_MAP_ROTATION);
    3.46 ++
    3.47 ++	m_normalRotation = (U16)(abs(normalMapRotation));
    3.48 ++}
    3.49 + 
    3.50 + void LLRenderMaterialEntry::LLRenderMaterial::asLLSD( LLSD& dest ) const
    3.51 + {
    3.52 +@@ -193,20 +231,45 @@
    3.53 + 	dest["NormOffsetY"] = (S32)m_normalOffsetY;
    3.54 + 	dest["NormRepeatX"] = m_normalRepeatX;
    3.55 + 	dest["NormRepeatY"] = m_normalRepeatY;
    3.56 +-	dest["NormRotation"] = (S32)m_normalRotation;
    3.57 ++
    3.58 ++	S32 value = (S32)m_normalMapRotation;
    3.59 ++
    3.60 ++	// If we don't have the flag for new rotations set,
    3.61 ++	// then we need to convert it now
    3.62 ++	if (!(m_flags & kNewNormalMapRotation))
    3.63 ++	{
    3.64 ++		F32 old_radians = ((F32)m_normalMapRotation / 10000.0f)
    3.65 ++		S32 new_val	    = (S32)(old_radians * 100.0f);
    3.66 ++		setNormalMapRotation(new_Val);
    3.67 ++	}
    3.68 ++
    3.69 ++	dest["NormRotation"] = (m_flags & kNormalMapRotationNegative) ? -(S32)m_normalRotation : (S32)m_normalRotation;
    3.70 + 
    3.71 + 	dest["SpecOffsetX"] = (S32)m_specularOffsetX;
    3.72 + 	dest["SpecOffsetY"] = (S32)m_specularOffsetY;
    3.73 + 	dest["SpecRepeatX"] = m_specularRepeatX;
    3.74 + 	dest["SpecRepeatY"] = m_specularRepeatY;
    3.75 +-	dest["SpecRotation"] = (S32)m_specularRotation;
    3.76 ++
    3.77 ++
    3.78 ++	value = (S32)m_specularRotation;
    3.79 ++
    3.80 ++	// If we don't have the flag for new rotations set,
    3.81 ++	// then we need to convert it now
    3.82 ++	if (!(m_flags & kNewSpecularMapRotation))
    3.83 ++	{
    3.84 ++		F32 old_radians = ((F32)m_specularMapRotation / 10000.0f)
    3.85 ++		S32 new_val	    = (S32)(old_radians * 100.0f);
    3.86 ++		setSpecularMapRotation(new_Val);
    3.87 ++	}
    3.88 ++
    3.89 ++	dest["SpecRotation"] = (m_flags & kSpecularMapRotationNegative) ? -(S32)m_specularRotation : (S32)m_specularRotation;
    3.90 + 
    3.91 + 	dest["SpecMap"] = m_specularMap;
    3.92 + 	dest["SpecColor"] = m_specularLightColor.getValue();
    3.93 + 	dest["SpecExp"] = (S32)m_specularLightExponent;
    3.94 + 	dest["EnvIntensity"] = (S32)m_environmentIntensity;
    3.95 + 	dest["AlphaMaskCutoff"] = (S32)m_alphaMaskCutoff;
    3.96 +-	dest["DiffuseAlphaMode"] = (S32)m_diffuseAlphaMode;
    3.97 ++	dest["DiffuseAlphaMode"] = (S32)(m_diffuseAlphaMode & 0xF);
    3.98 + 	
    3.99 + }
   3.100 + 
   3.101 +@@ -217,7 +280,10 @@
   3.102 + 	m_normalOffsetY = (U16)materialDefinition["NormOffsetY"].asInteger();
   3.103 + 	m_normalRepeatX = materialDefinition["NormRepeatX"].asInteger();
   3.104 + 	m_normalRepeatY = materialDefinition["NormRepeatY"].asInteger();
   3.105 +-	m_normalRotation = (U16)materialDefinition["NormRotation"].asInteger();
   3.106 ++
   3.107 ++	S32 normalRotation = materialDefinition["NormRotation"].asInteger();
   3.108 ++
   3.109 ++	setNormalMapRotation(normalRotation);
   3.110 + 
   3.111 + 	m_specularMap = materialDefinition["SpecMap"].asUUID();
   3.112 + 
   3.113 +@@ -225,7 +291,10 @@
   3.114 + 	m_specularOffsetY = (U16)materialDefinition["SpecOffsetY"].asInteger();
   3.115 + 	m_specularRepeatX = materialDefinition["SpecRepeatX"].asInteger();
   3.116 + 	m_specularRepeatY = materialDefinition["SpecRepeatY"].asInteger();
   3.117 +-	m_specularRotation = (U16)materialDefinition["SpecRotation"].asInteger();
   3.118 ++
   3.119 ++	S32 specularRotation = materialDefinition["SpecRotation"].asInteger();
   3.120 ++
   3.121 ++	setSpecularMapRotation(specularRotation);
   3.122 + 
   3.123 + 	m_specularLightColor.setValue( materialDefinition["SpecColor"] );
   3.124 + 	m_specularLightExponent = (U8)materialDefinition["SpecExp"].asInteger();
   3.125 +diff -r fe4bab01522e indra/llprimitive/llrendermaterialtable.h
   3.126 +--- a/indra/llprimitive/llrendermaterialtable.h	Wed May 15 17:57:21 2013 +0000
   3.127 ++++ b/indra/llprimitive/llrendermaterialtable.h	Wed May 22 14:23:04 2013 -0700
   3.128 +@@ -89,11 +89,17 @@
   3.129 + 
   3.130 + 	void computeID();
   3.131 + 
   3.132 ++
   3.133 + 	struct LLRenderMaterial
   3.134 + 	{
   3.135 + 		void asLLSD( LLSD& dest ) const;
   3.136 + 		void setFromLLSD( const LLSD& materialDefinition );
   3.137 + 
   3.138 ++		void setNormalMapRotation(S32 v);
   3.139 ++		void setSpecularMapRotation(S32 v);
   3.140 ++
   3.141 ++		const S32 MAX_MATERIAL_MAP_ROTATION = 62800;
   3.142 ++
   3.143 + 		// 36 bytes
   3.144 + 		LLUUID m_normalMap;
   3.145 + 		LLUUID m_specularMap;
   3.146 +@@ -119,7 +125,20 @@
   3.147 + 		U8 m_specularLightExponent;
   3.148 + 		U8 m_environmentIntensity;
   3.149 + 		U8 m_alphaMaskCutoff;
   3.150 +-		U8 m_diffuseAlphaMode;
   3.151 ++		U8 m_diffuseAlphaMode : 4;
   3.152 ++		U8 m_flags            : 4;
   3.153 ++	};
   3.154 ++
   3.155 ++	// Flags stored in LLRenderMaterial::m_flags to differentiate 'old' rotation format
   3.156 ++	// which doesn't handle negative or large rotations correctly from new format.
   3.157 ++	// All ancient materials will have these flags unset as the values for diffuseAlphaMode
   3.158 ++	// from which the bits were stolen never used more than the bottom 2 bits.
   3.159 ++	//
   3.160 ++	enum RenderMaterialFlags {
   3.161 ++	 kNewNormalMapRotation 		= 0x1,
   3.162 ++	 kNewSpecularMapRotation 	= 0x2,
   3.163 ++	 kNormalMapRotationNegative 	= 0x4,
   3.164 ++	 kSpecularMapRotationNegative   = 0x8
   3.165 + 	};
   3.166 + 
   3.167 + 	friend struct eastl::hash<LLRenderMaterial>;
     4.1 --- a/autobuild.xml	Thu Jul 18 15:14:55 2013 -0400
     4.2 +++ b/autobuild.xml	Thu Jul 18 18:43:58 2013 -0400
     4.3 @@ -498,9 +498,9 @@
     4.4              <key>archive</key>
     4.5              <map>
     4.6                <key>hash</key>
     4.7 -	      <string>10352aab979c333a52dbad21b6e6fba9</string>
     4.8 +              <string>10352aab979c333a52dbad21b6e6fba9</string>
     4.9                <key>url</key>
    4.10 -	      <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>
    4.11 +              <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>
    4.12              </map>
    4.13              <key>name</key>
    4.14              <string>darwin</string>
    4.15 @@ -510,7 +510,7 @@
    4.16              <key>archive</key>
    4.17              <map>
    4.18                <key>hash</key>
    4.19 -          <string>79e45527aa9fb90b813599dff5ce01a7</string>
    4.20 +              <string>79e45527aa9fb90b813599dff5ce01a7</string>
    4.21                <key>url</key>
    4.22                <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>
    4.23              </map>
    4.24 @@ -522,9 +522,9 @@
    4.25              <key>archive</key>
    4.26              <map>
    4.27                <key>hash</key>
    4.28 -	      <string>0980cdf98a322a780ba739e324d0b955</string>
    4.29 +	      <string>91752db72202807cffb33c1ec3fd90fc</string>
    4.30                <key>url</key>
    4.31 -	      <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>
    4.32 +	      <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>
    4.33              </map>
    4.34              <key>name</key>
    4.35              <string>windows</string>
    4.36 @@ -747,7 +747,6 @@
    4.37            </map>
    4.38          </map>
    4.39        </map>
    4.40 -
    4.41        <key>google_breakpad</key>
    4.42        <map>
    4.43          <key>license</key>
    4.44 @@ -763,9 +762,9 @@
    4.45              <key>archive</key>
    4.46              <map>
    4.47             <key>hash</key>
    4.48 -	   <string>aff5566e04003de0383941981198e04e</string>
    4.49 +	      <string>aff5566e04003de0383941981198e04e</string>
    4.50            <key>url</key>
    4.51 -          <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>
    4.52 +              <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>
    4.53              </map>
    4.54              <key>name</key>
    4.55              <string>darwin</string>
    4.56 @@ -777,7 +776,7 @@
    4.57               <key>hash</key>
    4.58  	         <string>52257e5eb166a0b69c9c0c38f6e1920e</string>
    4.59               <key>url</key>
    4.60 -	         <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>
    4.61 +              <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>
    4.62              </map>
    4.63              <key>name</key>
    4.64              <string>linux</string>
    4.65 @@ -789,7 +788,7 @@
    4.66                <key>hash</key>
    4.67  	      <string>d812a6dfcabe6528198a3191068dac09</string>
    4.68                <key>url</key>
    4.69 -             <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>
    4.70 +              <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>
    4.71              </map>
    4.72              <key>name</key>
    4.73              <string>windows</string>
    4.74 @@ -835,9 +834,45 @@
    4.75              <key>archive</key>
    4.76              <map>
    4.77                <key>hash</key>
    4.78 -              <string>98994d5b0b4b3d43be22aa6a5c36e6fa</string>
    4.79 +              <string>d2542614df9dd99cbb5ff67e76d4a6c1</string>
    4.80                <key>url</key>
    4.81 -		<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>
    4.82 +              <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>
    4.83 +            </map>
    4.84 +            <key>name</key>
    4.85 +            <string>windows</string>
    4.86 +          </map>
    4.87 +        </map>
    4.88 +      </map>
    4.89 +      <key>gperftools</key>
    4.90 +      <map>
    4.91 +        <key>license</key>
    4.92 +        <string>bsd</string>
    4.93 +        <key>license_file</key>
    4.94 +        <string>LICENSES/gperftools.txt</string>
    4.95 +        <key>name</key>
    4.96 +        <string>gperftools</string>
    4.97 +        <key>platforms</key>
    4.98 +        <map>
    4.99 +          <key>linux</key>
   4.100 +          <map>
   4.101 +            <key>archive</key>
   4.102 +            <map>
   4.103 +              <key>hash</key>
   4.104 +              <string>8aedfdcf670348c18a9991ae1b384a61</string>
   4.105 +              <key>url</key>
   4.106 +              <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>
   4.107 +            </map>
   4.108 +            <key>name</key>
   4.109 +            <string>linux</string>
   4.110 +          </map>
   4.111 +          <key>windows</key>
   4.112 +          <map>
   4.113 +            <key>archive</key>
   4.114 +            <map>
   4.115 +              <key>hash</key>
   4.116 +              <string>f62841804acb91e1309603a84f3f0ce8</string>
   4.117 +              <key>url</key>
   4.118 +              <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>
   4.119              </map>
   4.120              <key>name</key>
   4.121              <string>windows</string>
   4.122 @@ -2532,7 +2567,7 @@
   4.123                    <string>"Visual Studio 10"</string>
   4.124                    <string>-DUNATTENDED:BOOL=ON</string>
   4.125                    <string>-DUSE_KDU=FALSE</string>
   4.126 -                </array>
   4.127 +                  </array>
   4.128                </map>
   4.129                <key>name</key>
   4.130                <string>DebugOS</string>
   4.131 @@ -2620,7 +2655,7 @@
   4.132                    <string>-DUNATTENDED:BOOL=ON</string>
   4.133                    <string>-DINSTALL_PROPRIETARY=FALSE</string>
   4.134                    <string>-DUSE_KDU=FALSE</string>
   4.135 -                </array>
   4.136 +                  </array>
   4.137                </map>
   4.138                <key>name</key>
   4.139                <string>RelWithDebInfoOS</string>
   4.140 @@ -2707,7 +2742,7 @@
   4.141                    <string>-DUNATTENDED:BOOL=ON</string>
   4.142                    <string>-DINSTALL_PROPRIETARY=FALSE</string>
   4.143                    <string>-DUSE_KDU=FALSE</string>
   4.144 -                </array>
   4.145 +                  </array>
   4.146                </map>
   4.147                <key>name</key>
   4.148                <string>ReleaseOS</string>
     5.1 --- a/doc/contributions.txt	Thu Jul 18 15:14:55 2013 -0400
     5.2 +++ b/doc/contributions.txt	Thu Jul 18 18:43:58 2013 -0400
     5.3 @@ -404,6 +404,7 @@
     5.4  Geenz Spad
     5.5  	STORM-1823
     5.6  	STORM-1900
     5.7 +	NORSPEC-229
     5.8  Gene Frostbite
     5.9  GeneJ Composer
    5.10  Geneko Nemeth
    5.11 @@ -647,6 +648,7 @@
    5.12  	STORM-1872
    5.13  	STORM-1858
    5.14  	STORM-1862
    5.15 +	OPEN-161
    5.16  Kadah Coba
    5.17  	STORM-1060
    5.18      STORM-1843
    5.19 @@ -1023,6 +1025,7 @@
    5.20  	VWR-287
    5.21  Sachi Vixen
    5.22  Sahkolihaa Contepomi
    5.23 +	MATBUG-102
    5.24  Saii Hallard
    5.25  SaintLEOlions Zimer
    5.26  Salahzar Stenvaag
    5.27 @@ -1173,6 +1176,7 @@
    5.28  	SNOW-746
    5.29  	VWR-12385
    5.30  	VWR-20893
    5.31 +	OPEN-161
    5.32  Templar Merlin
    5.33  tenebrous pau
    5.34  	VWR-247
    5.35 @@ -1240,6 +1244,7 @@
    5.36  	VWR-2681
    5.37  Vaalith Jinn
    5.38      STORM-64
    5.39 +    MATBUG-8
    5.40  Vector Hastings
    5.41  	VWR-8726
    5.42  Veritas Raymaker
     6.1 --- a/indra/cmake/APR.cmake	Thu Jul 18 15:14:55 2013 -0400
     6.2 +++ b/indra/cmake/APR.cmake	Thu Jul 18 18:43:58 2013 -0400
     6.3 @@ -49,7 +49,7 @@
     6.4    set(APR_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/apr-1)
     6.5  
     6.6    if (LINUX)
     6.7 -    list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} uuid)
     6.8 +      list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} uuid)
     6.9      list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} rt)
    6.10    endif (LINUX)
    6.11  endif (STANDALONE)
     7.1 --- a/indra/cmake/BuildVersion.cmake	Thu Jul 18 15:14:55 2013 -0400
     7.2 +++ b/indra/cmake/BuildVersion.cmake	Thu Jul 18 18:43:58 2013 -0400
     7.3 @@ -18,7 +18,7 @@
     7.4             find_program(MERCURIAL hg)
     7.5             if (DEFINED MERCURIAL)
     7.6                execute_process(
     7.7 -                 COMMAND ${MERCURIAL} parents --template "{rev}"
     7.8 +                 COMMAND ${MERCURIAL} log -r tip --template "{p1rev}"
     7.9                   OUTPUT_VARIABLE VIEWER_VERSION_REVISION
    7.10                   OUTPUT_STRIP_TRAILING_WHITESPACE
    7.11                   )
     8.1 --- a/indra/cmake/CMakeLists.txt	Thu Jul 18 15:14:55 2013 -0400
     8.2 +++ b/indra/cmake/CMakeLists.txt	Thu Jul 18 18:43:58 2013 -0400
     8.3 @@ -12,6 +12,7 @@
     8.4      Audio.cmake
     8.5      BerkeleyDB.cmake
     8.6      Boost.cmake
     8.7 +    BuildVersion.cmake
     8.8      CARes.cmake
     8.9      CMakeCopyIfDifferent.cmake
    8.10      ConfigurePkgConfig.cmake
     9.1 --- a/indra/cmake/DragDrop.cmake	Thu Jul 18 15:14:55 2013 -0400
     9.2 +++ b/indra/cmake/DragDrop.cmake	Thu Jul 18 18:43:58 2013 -0400
     9.3 @@ -1,20 +1,20 @@
     9.4  # -*- cmake -*-
     9.5  
     9.6 -set(OS_DRAG_DROP ON CACHE BOOL "Build the viewer with OS level drag and drop turned on or off")
     9.7 +  set(OS_DRAG_DROP ON CACHE BOOL "Build the viewer with OS level drag and drop turned on or off")
     9.8  
     9.9 -if (OS_DRAG_DROP)
    9.10 +  if (OS_DRAG_DROP)
    9.11  
    9.12 -  if (WINDOWS)
    9.13 -    add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
    9.14 -  endif (WINDOWS)
    9.15 +    if (WINDOWS)
    9.16 +      add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
    9.17 +    endif (WINDOWS)
    9.18  
    9.19 -  if (DARWIN)
    9.20 -    add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
    9.21 -  endif (DARWIN)
    9.22 +    if (DARWIN)
    9.23 +      add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
    9.24 +    endif (DARWIN)
    9.25  
    9.26 -  if (LINUX)
    9.27 -    add_definitions(-DLL_OS_DRAGDROP_ENABLED=0)
    9.28 -  endif (LINUX)
    9.29 +    if (LINUX)
    9.30 +      add_definitions(-DLL_OS_DRAGDROP_ENABLED=0)
    9.31 +    endif (LINUX)
    9.32  
    9.33 -endif (OS_DRAG_DROP)
    9.34 +  endif (OS_DRAG_DROP)
    9.35  
    10.1 --- a/indra/cmake/Havok.cmake	Thu Jul 18 15:14:55 2013 -0400
    10.2 +++ b/indra/cmake/Havok.cmake	Thu Jul 18 18:43:58 2013 -0400
    10.3 @@ -12,14 +12,14 @@
    10.4  set(HAVOK_RELEASE_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)
    10.5  
    10.6  if (LL_DEBUG_HAVOK)
    10.7 -  if (WIN32)
    10.8 -    # Always link relwithdebinfo to havok-hybrid on windows.
    10.9 -    set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-hybrid)
   10.10 -  else (WIN32)
   10.11 -    set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug)
   10.12 -  endif (WIN32)
   10.13 +   if (WIN32)
   10.14 +      # Always link relwithdebinfo to havok-hybrid on windows.
   10.15 +      set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-hybrid)
   10.16 +   else (WIN32)
   10.17 +      set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug)
   10.18 +   endif (WIN32)
   10.19  else (LL_DEBUG_HAVOK)
   10.20 -  set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)
   10.21 +   set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)
   10.22  endif (LL_DEBUG_HAVOK)
   10.23  
   10.24  set(HAVOK_LIBS
   10.25 @@ -51,14 +51,14 @@
   10.26  
   10.27  # *TODO: Figure out why we need to extract like this...
   10.28  foreach(HAVOK_LIB ${HAVOK_LIBS})
   10.29 -  find_library(HAVOK_DEBUG_LIB_${HAVOK_LIB}   ${HAVOK_LIB} PATHS ${HAVOK_DEBUG_LIBRARY_PATH})
   10.30 -  find_library(HAVOK_RELEASE_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELEASE_LIBRARY_PATH})
   10.31 -  find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH})
   10.32 -  
   10.33 -  if(LINUX)
   10.34 -    set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}")
   10.35 -    set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}")
   10.36 -    set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}")
   10.37 +        find_library(HAVOK_DEBUG_LIB_${HAVOK_LIB}   ${HAVOK_LIB} PATHS ${HAVOK_DEBUG_LIBRARY_PATH})
   10.38 +        find_library(HAVOK_RELEASE_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELEASE_LIBRARY_PATH})
   10.39 +        find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH})
   10.40 +        
   10.41 +        if(LINUX)
   10.42 +            set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}")
   10.43 +            set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}")
   10.44 +            set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}")
   10.45  
   10.46      # Try to avoid extracting havok library each time we run cmake.
   10.47      if("${havok_${HAVOK_LIB}_extracted}" STREQUAL "" AND EXISTS "${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted")
   10.48 @@ -77,35 +77,35 @@
   10.49        if(DEBUG_PREBUILT)
   10.50          MESSAGE(STATUS "${cmd} ${debug_dir}")
   10.51        endif(DEBUG_PREBUILT)
   10.52 -      exec_program( ${cmd} ${HAVOK_DEBUG_LIBRARY_PATH} ARGS ${debug_dir} OUTPUT_VARIABLE rv)
   10.53 +            exec_program( ${cmd} ${HAVOK_DEBUG_LIBRARY_PATH} ARGS ${debug_dir} OUTPUT_VARIABLE rv)
   10.54  
   10.55        if(DEBUG_PREBUILT)
   10.56          MESSAGE(STATUS "${cmd} ${release_dir}")
   10.57        endif(DEBUG_PREBUILT)
   10.58 -      exec_program( ${cmd} ${HAVOK_RELEASE_LIBRARY_PATH} ARGS ${release_dir} OUTPUT_VARIABLE rv)
   10.59 +            exec_program( ${cmd} ${HAVOK_RELEASE_LIBRARY_PATH} ARGS ${release_dir} OUTPUT_VARIABLE rv)
   10.60  
   10.61        if(DEBUG_PREBUILT)
   10.62          MESSAGE(STATUS "${cmd} ${relwithdebinfo_dir}")
   10.63        endif(DEBUG_PREBUILT)
   10.64 -      exec_program( ${cmd} ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH} ARGS ${relwithdebinfo_dir} OUTPUT_VARIABLE rv)
   10.65 +            exec_program( ${cmd} ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH} ARGS ${relwithdebinfo_dir} OUTPUT_VARIABLE rv)
   10.66  
   10.67 -      set(cmd "ar")
   10.68 -      set(arg " -xv")
   10.69 -      set(arg "${arg} ../lib${HAVOK_LIB}.a")
   10.70 +            set(cmd "ar")
   10.71 +            set(arg " -xv")
   10.72 +            set(arg "${arg} ../lib${HAVOK_LIB}.a")
   10.73        if(DEBUG_PREBUILT)
   10.74          MESSAGE(STATUS "cd ${debug_dir} && ${cmd} ${arg}")
   10.75        endif(DEBUG_PREBUILT)
   10.76 -      exec_program( ${cmd} ${debug_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
   10.77 +            exec_program( ${cmd} ${debug_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
   10.78  
   10.79        if(DEBUG_PREBUILT)
   10.80          MESSAGE(STATUS "cd ${release_dir} && ${cmd} ${arg}")
   10.81        endif(DEBUG_PREBUILT)
   10.82 -      exec_program( ${cmd} ${release_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
   10.83 +            exec_program( ${cmd} ${release_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
   10.84  
   10.85        if(DEBUG_PREBUILT)
   10.86          MESSAGE(STATUS "cd ${relwithdebinfo_dir} && ${cmd} ${arg}")
   10.87        endif(DEBUG_PREBUILT)
   10.88 -      exec_program( ${cmd} ${relwithdebinfo_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
   10.89 +            exec_program( ${cmd} ${relwithdebinfo_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
   10.90  
   10.91        # Just assume success for now.
   10.92        set(havok_${HAVOK_LIB}_extracted 0)
   10.93 @@ -113,9 +113,9 @@
   10.94  
   10.95      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)
   10.96  
   10.97 -    file(GLOB extracted_debug "${debug_dir}/*.o")
   10.98 -    file(GLOB extracted_release "${release_dir}/*.o")
   10.99 -    file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o")
  10.100 +            file(GLOB extracted_debug "${debug_dir}/*.o")
  10.101 +            file(GLOB extracted_release "${release_dir}/*.o")
  10.102 +            file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o")
  10.103  
  10.104      if(DEBUG_PREBUILT)
  10.105        MESSAGE(STATUS "extracted_debug ${debug_dir}/*.o")
  10.106 @@ -123,15 +123,15 @@
  10.107        MESSAGE(STATUS "extracted_relwithdebinfo ${relwithdebinfo_dir}/*.o")
  10.108      endif(DEBUG_PREBUILT)
  10.109  
  10.110 -    list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug})
  10.111 -    list(APPEND HK_RELEASE_LIBRARIES ${extracted_release})
  10.112 -    list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo})
  10.113 -  else(LINUX)
  10.114 -  # Win32
  10.115 -    list(APPEND HK_DEBUG_LIBRARIES   ${HAVOK_DEBUG_LIB_${HAVOK_LIB}})
  10.116 -    list(APPEND HK_RELEASE_LIBRARIES ${HAVOK_RELEASE_LIB_${HAVOK_LIB}})
  10.117 -    list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB}})
  10.118 -  endif (LINUX)
  10.119 +            list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug})
  10.120 +            list(APPEND HK_RELEASE_LIBRARIES ${extracted_release})
  10.121 +            list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo})
  10.122 +        else(LINUX)
  10.123 +        # Win32
  10.124 +            list(APPEND HK_DEBUG_LIBRARIES   ${HAVOK_DEBUG_LIB_${HAVOK_LIB}})
  10.125 +            list(APPEND HK_RELEASE_LIBRARIES ${HAVOK_RELEASE_LIB_${HAVOK_LIB}})
  10.126 +            list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB}})
  10.127 +        endif (LINUX)
  10.128  endforeach(HAVOK_LIB)
  10.129  
  10.130  endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
    11.1 --- a/indra/cmake/LLPrimitive.cmake	Thu Jul 18 15:14:55 2013 -0400
    11.2 +++ b/indra/cmake/LLPrimitive.cmake	Thu Jul 18 18:43:58 2013 -0400
    11.3 @@ -2,6 +2,8 @@
    11.4  
    11.5  # these should be moved to their own cmake file
    11.6  include(Prebuilt)
    11.7 +include(Boost)
    11.8 +
    11.9  use_prebuilt_binary(colladadom)
   11.10  use_prebuilt_binary(pcre)
   11.11  use_prebuilt_binary(libxml)
   11.12 @@ -15,10 +17,7 @@
   11.13          optimized llprimitive
   11.14          debug libcollada14dom22-d
   11.15          optimized libcollada14dom22
   11.16 -        debug libboost_filesystem-mt-gd
   11.17 -        optimized libboost_filesystem-mt
   11.18 -        debug libboost_system-mt-gd
   11.19 -        optimized libboost_system-mt
   11.20 +        ${BOOST_SYSTEM_LIBRARIES}
   11.21          )
   11.22  else (WINDOWS)
   11.23      set(LLPRIMITIVE_LIBRARIES 
    12.1 --- a/indra/cmake/LLRender.cmake	Thu Jul 18 15:14:55 2013 -0400
    12.2 +++ b/indra/cmake/LLRender.cmake	Thu Jul 18 18:43:58 2013 -0400
    12.3 @@ -11,8 +11,8 @@
    12.4  
    12.5  if (BUILD_HEADLESS)
    12.6    set(LLRENDER_HEADLESS_LIBRARIES
    12.7 -    llrenderheadless
    12.8 -    )
    12.9 +      llrenderheadless
   12.10 +      )
   12.11  endif (BUILD_HEADLESS)
   12.12  set(LLRENDER_LIBRARIES
   12.13      llrender
    13.1 --- a/indra/cmake/LLWindow.cmake	Thu Jul 18 15:14:55 2013 -0400
    13.2 +++ b/indra/cmake/LLWindow.cmake	Thu Jul 18 18:43:58 2013 -0400
    13.3 @@ -33,10 +33,10 @@
    13.4  
    13.5  if (BUILD_HEADLESS)
    13.6    set(LLWINDOW_HEADLESS_LIBRARIES
    13.7 -    llwindowheadless
    13.8 -    )
    13.9 +      llwindowheadless
   13.10 +      )
   13.11  endif (BUILD_HEADLESS)
   13.12  
   13.13 -set(LLWINDOW_LIBRARIES
   13.14 -    llwindow
   13.15 -    )
   13.16 +  set(LLWINDOW_LIBRARIES
   13.17 +      llwindow
   13.18 +      )
    14.1 --- a/indra/cmake/VisualLeakDetector.cmake	Thu Jul 18 15:14:55 2013 -0400
    14.2 +++ b/indra/cmake/VisualLeakDetector.cmake	Thu Jul 18 18:43:58 2013 -0400
    14.3 @@ -1,12 +1,12 @@
    14.4  # -*- cmake -*-
    14.5  
    14.6 -set(INCLUDE_VLD_CMAKE OFF CACHE BOOL "Build the Windows viewer with Visual Leak Detector turned on or off")
    14.7 +  set(INCLUDE_VLD_CMAKE OFF CACHE BOOL "Build the Windows viewer with Visual Leak Detector turned on or off")
    14.8  
    14.9 -if (INCLUDE_VLD_CMAKE)
   14.10 +  if (INCLUDE_VLD_CMAKE)
   14.11  
   14.12 -  if (WINDOWS)
   14.13 -    add_definitions(-DINCLUDE_VLD=1)
   14.14 -  endif (WINDOWS)
   14.15 +    if (WINDOWS)
   14.16 +      add_definitions(-DINCLUDE_VLD=1)
   14.17 +    endif (WINDOWS)
   14.18  
   14.19 -endif (INCLUDE_VLD_CMAKE)
   14.20 +  endif (INCLUDE_VLD_CMAKE)
   14.21  
    15.1 --- a/indra/lib/python/indra/util/llversion.py	Thu Jul 18 15:14:55 2013 -0400
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,107 +0,0 @@
    15.4 -#!/usr/bin/env python
    15.5 -"""\
    15.6 -@file  llversion.py
    15.7 -@brief Parses llcommon/llversionserver.h and llcommon/llversionviewer.h
    15.8 -       for the version string and channel string.
    15.9 -       Parses hg info for branch and revision.
   15.10 -
   15.11 -$LicenseInfo:firstyear=2006&license=mit$
   15.12 -
   15.13 -Copyright (c) 2006-2009, Linden Research, Inc.
   15.14 -
   15.15 -Permission is hereby granted, free of charge, to any person obtaining a copy
   15.16 -of this software and associated documentation files (the "Software"), to deal
   15.17 -in the Software without restriction, including without limitation the rights
   15.18 -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   15.19 -copies of the Software, and to permit persons to whom the Software is
   15.20 -furnished to do so, subject to the following conditions:
   15.21 -
   15.22 -The above copyright notice and this permission notice shall be included in
   15.23 -all copies or substantial portions of the Software.
   15.24 -
   15.25 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   15.26 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   15.27 -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   15.28 -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   15.29 -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   15.30 -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   15.31 -THE SOFTWARE.
   15.32 -$/LicenseInfo$
   15.33 -"""
   15.34 -
   15.35 -import re, sys, os, subprocess
   15.36 -
   15.37 -# Methods for gathering version information from
   15.38 -# llversionviewer.h and llversionserver.h
   15.39 -
   15.40 -def get_src_root():
   15.41 -    indra_lib_python_indra_path = os.path.dirname(__file__)
   15.42 -    return os.path.abspath(os.path.realpath(indra_lib_python_indra_path + "/../../../../../"))
   15.43 -
   15.44 -def get_version_file_contents(version_type):
   15.45 -    filepath = get_src_root() + '/indra/llcommon/llversion%s.h' % version_type
   15.46 -    file = open(filepath,"r")
   15.47 -    file_str = file.read()
   15.48 -    file.close()
   15.49 -    return file_str
   15.50 -
   15.51 -def get_version(version_type):
   15.52 -    file_str = get_version_file_contents(version_type)
   15.53 -    m = re.search('const S32 LL_VERSION_MAJOR = (\d+);', file_str)
   15.54 -    VER_MAJOR = m.group(1)
   15.55 -    m = re.search('const S32 LL_VERSION_MINOR = (\d+);', file_str)
   15.56 -    VER_MINOR = m.group(1)
   15.57 -    m = re.search('const S32 LL_VERSION_PATCH = (\d+);', file_str)
   15.58 -    VER_PATCH = m.group(1)
   15.59 -    m = re.search('const S32 LL_VERSION_BUILD = (\d+);', file_str)
   15.60 -    VER_BUILD = m.group(1)
   15.61 -    version = "%(VER_MAJOR)s.%(VER_MINOR)s.%(VER_PATCH)s.%(VER_BUILD)s" % locals()
   15.62 -    return version
   15.63 -
   15.64 -def get_channel(version_type):
   15.65 -    file_str = get_version_file_contents(version_type)
   15.66 -    m = re.search('const char \* const LL_CHANNEL = "(.+)";', file_str)
   15.67 -    return m.group(1)
   15.68 -    
   15.69 -def get_viewer_version():
   15.70 -    return get_version('viewer')
   15.71 -
   15.72 -def get_server_version():
   15.73 -    return get_version('server')
   15.74 -
   15.75 -def get_viewer_channel():
   15.76 -    return get_channel('viewer')
   15.77 -
   15.78 -def get_server_channel():
   15.79 -    return get_channel('server')
   15.80 -
   15.81 -# Methods for gathering hg information
   15.82 -def get_hg_repo():
   15.83 -    child = subprocess.Popen(["hg","showconfig","paths.default"], stdout=subprocess.PIPE)
   15.84 -    output, error = child.communicate()
   15.85 -    status = child.returncode
   15.86 -    if status:
   15.87 -        print >> sys.stderr, error
   15.88 -        sys.exit(1)
   15.89 -    if not output:
   15.90 -        print >> sys.stderr, 'ERROR: cannot find repo we cloned from'
   15.91 -        sys.exit(1)
   15.92 -    return output
   15.93 -
   15.94 -def get_hg_changeset():
   15.95 -    # The right thing to do would be to use the *global* revision id:
   15.96 -    #     "hg id -i"
   15.97 -    # For the moment though, we use the parent revision:
   15.98 -    child = subprocess.Popen(["hg","parents","--template","{rev}"], stdout=subprocess.PIPE)
   15.99 -    output, error = child.communicate()
  15.100 -    status = child.returncode
  15.101 -    if status:
  15.102 -        print >> sys.stderr, error
  15.103 -        sys.exit(1)
  15.104 -    lines = output.splitlines()
  15.105 -    if len(lines) > 1:
  15.106 -        print >> sys.stderr, 'ERROR: working directory has %d parents' % len(lines)
  15.107 -    return lines[0]
  15.108 -
  15.109 -def using_hg():
  15.110 -    return os.path.isdir(os.path.join(get_src_root(), '.hg'))
    16.1 --- a/indra/linux_crash_logger/CMakeLists.txt	Thu Jul 18 15:14:55 2013 -0400
    16.2 +++ b/indra/linux_crash_logger/CMakeLists.txt	Thu Jul 18 18:43:58 2013 -0400
    16.3 @@ -26,6 +26,10 @@
    16.4      ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
    16.5      ${LLXML_SYSTEM_INCLUDE_DIRS}
    16.6      )
    16.7 +include_directories(SYSTEM
    16.8 +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
    16.9 +    ${LLXML_SYSTEM_INCLUDE_DIRS}
   16.10 +    )
   16.11  
   16.12  set(linux_crash_logger_SOURCE_FILES
   16.13      linux_crash_logger.cpp
    17.1 --- a/indra/llappearance/llpolymorph.cpp	Thu Jul 18 15:14:55 2013 -0400
    17.2 +++ b/indra/llappearance/llpolymorph.cpp	Thu Jul 18 18:43:58 2013 -0400
    17.3 @@ -597,19 +597,31 @@
    17.4  			norm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR);
    17.5  			scaled_normals[vert_index_mesh].add(norm);
    17.6  			norm = scaled_normals[vert_index_mesh];
    17.7 +
    17.8 +			// guard against degenerate input data before we create NaNs below!
    17.9 +			//
   17.10  			norm.normalize3fast();
   17.11  			normals[vert_index_mesh] = norm;
   17.12  
   17.13  			// calculate new binormals
   17.14  			LLVector4a binorm = mMorphData->mBinormals[vert_index_morph];
   17.15 +
   17.16 +			// guard against degenerate input data before we create NaNs below!
   17.17 +			//
   17.18 +			if (!binorm.isFinite3() || (binorm.dot3(binorm).getF32() <= F_APPROXIMATELY_ZERO))
   17.19 +			{
   17.20 +				binorm.set(1,0,0,1);
   17.21 +			}
   17.22 +
   17.23  			binorm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR);
   17.24  			scaled_binormals[vert_index_mesh].add(binorm);
   17.25  			LLVector4a tangent;
   17.26  			tangent.setCross3(scaled_binormals[vert_index_mesh], norm);
   17.27  			LLVector4a& normalized_binormal = binormals[vert_index_mesh];
   17.28 -			normalized_binormal.setCross3(norm, tangent); 
   17.29 +
   17.30 +			normalized_binormal.setCross3(norm, tangent); 			
   17.31  			normalized_binormal.normalize3fast();
   17.32 -			
   17.33 +
   17.34  			tex_coords[vert_index_mesh] += mMorphData->mTexCoords[vert_index_morph] * delta_weight * maskWeight;
   17.35  		}
   17.36  
    18.1 --- a/indra/llaudio/llaudioengine_fmodex.cpp	Thu Jul 18 15:14:55 2013 -0400
    18.2 +++ b/indra/llaudio/llaudioengine_fmodex.cpp	Thu Jul 18 18:43:58 2013 -0400
    18.3 @@ -67,7 +67,7 @@
    18.4  {
    18.5  	if(result == FMOD_OK)
    18.6  		return false;
    18.7 -	llwarns << string << " Error: " << FMOD_ErrorString(result) << llendl;
    18.8 +	lldebugs << string << " Error: " << FMOD_ErrorString(result) << llendl;
    18.9  	return true;
   18.10  }
   18.11  
   18.12 @@ -258,19 +258,29 @@
   18.13  
   18.14  	int r_numbuffers, r_samplerate, r_channels, r_bits;
   18.15  	unsigned int r_bufferlength;
   18.16 -	char r_name[256];
   18.17  	mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers);
   18.18 +	LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_bufferlength=" << r_bufferlength << " bytes" << LL_ENDL;
   18.19 +	LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_numbuffers=" << r_numbuffers << LL_ENDL;
   18.20 +
   18.21  	mSystem->getSoftwareFormat(&r_samplerate, NULL, &r_channels, NULL, NULL, &r_bits);
   18.22 -	mSystem->getDriverInfo(0, r_name, 255, 0);
   18.23 -	r_name[255] = '\0';
   18.24 -	int latency = (int)(1000.0f * r_bufferlength * r_numbuffers / r_samplerate);
   18.25 +	LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_samplerate=" << r_samplerate << "Hz" << LL_ENDL;
   18.26 +	LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_channels=" << r_channels << LL_ENDL;
   18.27 +	LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_bits =" << r_bits << LL_ENDL;
   18.28  
   18.29 -	LL_INFOS("AppInit") << "FMOD device: "<< r_name << "\n"
   18.30 -		<< "FMOD Ex parameters: " << r_samplerate << " Hz * " << r_channels << " * " <<r_bits <<" bit\n"
   18.31 -		<< "\tbuffer " << r_bufferlength << " * " << r_numbuffers << " (" << latency <<"ms)" << LL_ENDL;
   18.32 +	char r_name[512];
   18.33 +	mSystem->getDriverInfo(0, r_name, 511, 0);
   18.34 +	r_name[511] = '\0';
   18.35 +	LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_name=\"" << r_name << "\"" <<  LL_ENDL;
   18.36 +
   18.37 +	int latency = 100; // optimistic default - i suspect if sample rate is 0, everything breaks. 
   18.38 +	if ( r_samplerate != 0 )
   18.39 +		latency = (int)(1000.0f * r_bufferlength * r_numbuffers / r_samplerate);
   18.40 +	LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): latency=" << latency << "ms" << LL_ENDL;
   18.41  
   18.42  	mInited = true;
   18.43  
   18.44 +	LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): initialization complete." << LL_ENDL;
   18.45 +
   18.46  	return true;
   18.47  }
   18.48  
   18.49 @@ -310,8 +320,8 @@
   18.50  	llinfos << "LLAudioEngine_FMODEX::shutdown() closing FMOD Ex" << llendl;
   18.51  	if ( mSystem ) // speculative fix for MAINT-2657
   18.52  	{
   18.53 -		mSystem->close();
   18.54 -		mSystem->release();
   18.55 +	mSystem->close();
   18.56 +	mSystem->release();
   18.57  	}
   18.58  	llinfos << "LLAudioEngine_FMODEX::shutdown() done closing FMOD Ex" << llendl;
   18.59  
    19.1 --- a/indra/llaudio/llwindgen.h	Thu Jul 18 15:14:55 2013 -0400
    19.2 +++ b/indra/llaudio/llwindgen.h	Thu Jul 18 18:43:58 2013 -0400
    19.3 @@ -57,7 +57,7 @@
    19.4  	const U32 getInputSamplingRate() { return mInputSamplingRate; }
    19.5  	const F32 getNextSample();
    19.6  	const F32 getClampedSample(bool clamp, F32 sample);
    19.7 -
    19.8 +	
    19.9  	// newbuffer = the buffer passed from the previous DSP unit.
   19.10  	// numsamples = length in samples-per-channel at this mix time.
   19.11  	// NOTE: generates L/R interleaved stereo
   19.12 @@ -133,11 +133,11 @@
   19.13  				MIXBUFFERFORMAT_T	sample_left = (MIXBUFFERFORMAT_T)getClampedSample(clip, mLastSample - (F32)sample_right);
   19.14  				
   19.15  				*cursamplep = sample_left;
   19.16 -				++cursamplep;
   19.17 +					++cursamplep;
   19.18  				*cursamplep = sample_right;
   19.19 -				++cursamplep;
   19.20 +					++cursamplep;
   19.21 +				}
   19.22  			}
   19.23 -		}
   19.24  		
   19.25  		return newbuffer;
   19.26  	}
    20.1 --- a/indra/llcommon/llapp.cpp	Thu Jul 18 15:14:55 2013 -0400
    20.2 +++ b/indra/llcommon/llapp.cpp	Thu Jul 18 18:43:58 2013 -0400
    20.3 @@ -986,9 +986,9 @@
    20.4  	}
    20.5  
    20.6  	llinfos << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << llendl;
    20.7 -    // *NOTE:Mani - this code is stolen from LLApp, where its never actually used.
    20.8 +   // *NOTE:Mani - this code is stolen from LLApp, where its never actually used.
    20.9  	//OSMessageBox("Attach Debugger Now", "Error", OSMB_OK);
   20.10 -    // *TODO: Translate the signals/exceptions into cross-platform stuff
   20.11 +   // *TODO: Translate the signals/exceptions into cross-platform stuff
   20.12  	// Windows implementation
   20.13  	llinfos << "Entering Windows Exception Handler..." << llendl;
   20.14  
    21.1 --- a/indra/llcommon/llapr.cpp	Thu Jul 18 15:14:55 2013 -0400
    21.2 +++ b/indra/llcommon/llapr.cpp	Thu Jul 18 18:43:58 2013 -0400
    21.3 @@ -226,9 +226,7 @@
    21.4  		llassert_always(mNumActiveRef > 0) ;
    21.5  	}
    21.6  
    21.7 -	//paranoia check if the pool is jammed.
    21.8 -	//will remove the check before going to release.
    21.9 -	llassert_always(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ;
   21.10 +	llassert(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ;
   21.11  }
   21.12  
   21.13  BOOL LLVolatileAPRPool::isFull()
    22.1 --- a/indra/llcommon/llavatarname.h	Thu Jul 18 15:14:55 2013 -0400
    22.2 +++ b/indra/llcommon/llavatarname.h	Thu Jul 18 18:43:58 2013 -0400
    22.3 @@ -63,7 +63,7 @@
    22.4  	// For normal names, returns "James Linden (james.linden)"
    22.5  	// When display names are disabled returns just "James Linden"
    22.6  	std::string getCompleteName() const;
    22.7 -
    22.8 +	
    22.9  	// Returns "James Linden" or "bobsmith123 Resident" for backwards
   22.10  	// compatibility with systems like voice and muting
   22.11  	// *TODO: Eliminate this in favor of username only
    23.1 --- a/indra/llcommon/llcoros.cpp	Thu Jul 18 15:14:55 2013 -0400
    23.2 +++ b/indra/llcommon/llcoros.cpp	Thu Jul 18 18:43:58 2013 -0400
    23.3 @@ -60,7 +60,7 @@
    23.4          // since last tick?
    23.5          if (mi->second->exited())
    23.6          {
    23.7 -            LL_INFOS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << LL_ENDL;
    23.8 +			   LL_INFOS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << LL_ENDL;
    23.9              // The erase() call will invalidate its passed iterator value --
   23.10              // so increment mi FIRST -- but pass its original value to
   23.11              // erase(). This is what postincrement is all about.
   23.12 @@ -94,7 +94,7 @@
   23.13      {
   23.14          if (mCoros.find(name) == mCoros.end())
   23.15          {
   23.16 -            LL_INFOS("LLCoros") << "LLCoros: launching coroutine " << name << LL_ENDL;
   23.17 +			   LL_INFOS("LLCoros") << "LLCoros: launching coroutine " << name << LL_ENDL;
   23.18              return name;
   23.19          }
   23.20      }
    24.1 --- a/indra/llcommon/llerror.cpp	Thu Jul 18 15:14:55 2013 -0400
    24.2 +++ b/indra/llcommon/llerror.cpp	Thu Jul 18 18:43:58 2013 -0400
    24.3 @@ -201,10 +201,7 @@
    24.4  		virtual void recordMessage(LLError::ELevel level,
    24.5  								   const std::string& message)
    24.6  		{
    24.7 -			llutf16string utf16str =
    24.8 -				wstring_to_utf16str(utf8str_to_wstring(message));
    24.9 -			utf16str += '\n';
   24.10 -			OutputDebugString(utf16str.c_str());
   24.11 +			LL_WINDOWS_OUTPUT_DEBUG(message);
   24.12  		}
   24.13  	};
   24.14  #endif
   24.15 @@ -1401,5 +1398,27 @@
   24.16     {
   24.17         sIndex = 0 ;
   24.18     }
   24.19 +
   24.20 +#if LL_WINDOWS
   24.21 +	void LLOutputDebugUTF8(const std::string& s)
   24.22 +	{
   24.23 +		// Be careful when calling OutputDebugString as it throws DBG_PRINTEXCEPTION_C 
   24.24 +		// which works just fine under the windows debugger, but can cause users who
   24.25 +		// have enabled SEHOP exception chain validation to crash due to interactions
   24.26 +		// between the Win 32-bit exception handling and boost coroutine fiber stacks. BUG-2707
   24.27 +		//
   24.28 +		if (IsDebuggerPresent())
   24.29 +		{
   24.30 +			// Need UTF16 for Unicode OutputDebugString
   24.31 +			//
   24.32 +			if (s.size())
   24.33 +			{
   24.34 +				OutputDebugString(utf8str_to_utf16str(s).c_str());
   24.35 +				OutputDebugString(TEXT("\n"));
   24.36 +			}
   24.37 +		}
   24.38 +	}
   24.39 +#endif
   24.40 +
   24.41  }
   24.42  
    25.1 --- a/indra/llcommon/llerror.h	Thu Jul 18 15:14:55 2013 -0400
    25.2 +++ b/indra/llcommon/llerror.h	Thu Jul 18 18:43:58 2013 -0400
    25.3 @@ -34,7 +34,6 @@
    25.4  #include "llerrorlegacy.h"
    25.5  #include "stdtypes.h"
    25.6  
    25.7 -
    25.8  /** Error Logging Facility
    25.9  
   25.10  	Information for most users:
   25.11 @@ -199,8 +198,20 @@
   25.12         static void clear() ;
   25.13  	   static void end(std::ostringstream* _out) ;
   25.14     }; 
   25.15 +
   25.16 +#if LL_WINDOWS
   25.17 +	void LLOutputDebugUTF8(const std::string& s);
   25.18 +#endif
   25.19 +
   25.20  }
   25.21  
   25.22 +#if LL_WINDOWS
   25.23 +	// Macro accepting a std::string for display in windows debugging console
   25.24 +	#define LL_WINDOWS_OUTPUT_DEBUG(a) LLError::LLOutputDebugUTF8(a)
   25.25 +#else
   25.26 +	#define LL_WINDOWS_OUTPUT_DEBUG(a)
   25.27 +#endif
   25.28 +
   25.29  //this is cheaper than llcallstacks if no need to output other variables to call stacks. 
   25.30  #define llpushcallstacks LLError::LLCallStacks::push(__FUNCTION__, __LINE__)
   25.31  #define llcallstacks \
    26.1 --- a/indra/llcommon/llfasttimer.cpp	Thu Jul 18 15:14:55 2013 -0400
    26.2 +++ b/indra/llcommon/llfasttimer.cpp	Thu Jul 18 18:43:58 2013 -0400
    26.3 @@ -561,7 +561,7 @@
    26.4  	return mChildren;
    26.5  }
    26.6  
    26.7 -// static
    26.8 +//static
    26.9  LLFastTimer::NamedTimer& LLFastTimer::NamedTimer::getRootNamedTimer()
   26.10  {
   26.11          return *NamedTimerFactory::instance().getRootTimer();
    27.1 --- a/indra/llcommon/llfile.cpp	Thu Jul 18 15:14:55 2013 -0400
    27.2 +++ b/indra/llcommon/llfile.cpp	Thu Jul 18 18:43:58 2013 -0400
    27.3 @@ -438,7 +438,7 @@
    27.4  				_M_set_buffer(0);
    27.5  				__ret = traits_type::not_eof(__c);
    27.6  			}
    27.7 -		}
    27.8 +	}
    27.9  		else if (_M_buf_size > 1)
   27.10  		{
   27.11  			// Overflow in 'uncommitted' mode: set _M_writing, set
   27.12 @@ -496,11 +496,11 @@
   27.13  		if (__r == codecvt_base::ok || __r == codecvt_base::partial)
   27.14  			__blen = __bend - __buf;
   27.15  		else if (__r == codecvt_base::noconv)
   27.16 -		{
   27.17 +	{
   27.18  			// Same as the always_noconv case above.
   27.19  			__buf = reinterpret_cast<char*>(__ibuf);
   27.20  			__blen = __ilen;
   27.21 -		}
   27.22 +	}
   27.23  		else
   27.24  			__throw_ios_failure(__N("llstdio_filebuf::_convert_to_external "
   27.25  									"conversion error"));
   27.26 @@ -643,9 +643,9 @@
   27.27  							_M_ext_end, _M_ext_next,
   27.28  							this->eback(),
   27.29  							this->eback() + __buflen, __iend);
   27.30 -				}
   27.31 +}
   27.32  				if (__r == codecvt_base::noconv)
   27.33 -				{
   27.34 +{
   27.35  					size_t __avail = _M_ext_end - _M_ext_buf;
   27.36  					__ilen = std::min(__avail, __buflen);
   27.37  					traits_type::copy(this->eback(),
   27.38 @@ -806,15 +806,15 @@
   27.39  				__ret = fwrite(__buf, 1, __buffill, _M_file.file());
   27.40  			}
   27.41  			if (__ret == __buffill)
   27.42 -			{
   27.43 +	{
   27.44  				__ret += fwrite(reinterpret_cast<const char*>(__s), 1,
   27.45  								__n, _M_file.file());
   27.46 -			}
   27.47 +	}
   27.48  			if (__ret == __buffill + __n)
   27.49  			{
   27.50  				_M_set_buffer(0);
   27.51  				_M_writing = true;
   27.52 -			}
   27.53 +}
   27.54  			if (__ret > __buffill)
   27.55  				__ret -= __buffill;
   27.56  			else
   27.57 @@ -848,7 +848,7 @@
   27.58  #endif
   27.59  
   27.60  // explicit
   27.61 -llifstream::llifstream(const std::string& _Filename, 
   27.62 +llifstream::llifstream(const std::string& _Filename,
   27.63  		ios_base::openmode _Mode) : _M_filebuf(),
   27.64  #if LL_WINDOWS
   27.65  	std::istream(&_M_filebuf)
   27.66 @@ -877,7 +877,7 @@
   27.67  	if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0)
   27.68  	{
   27.69  		_Myios::setstate(ios_base::failbit);
   27.70 -	}
   27.71 +}
   27.72  }
   27.73  #else
   27.74  	std::istream()
   27.75 @@ -951,8 +951,8 @@
   27.76  #else
   27.77  		this->setstate(ios_base::failbit);
   27.78  #endif
   27.79 +		}
   27.80  	}
   27.81 -}
   27.82  
   27.83  
   27.84  /************** output file stream ********************************/
   27.85 @@ -1042,7 +1042,7 @@
   27.86  #if LL_WINDOWS
   27.87  	llutf16string wideName = utf8str_to_utf16str( _Filename );
   27.88  	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
   27.89 -	{
   27.90 +{
   27.91  		_Myios::setstate(ios_base::failbit);
   27.92  	}
   27.93  	else
    28.1 --- a/indra/llcommon/llfile.h	Thu Jul 18 15:14:55 2013 -0400
    28.2 +++ b/indra/llcommon/llfile.h	Thu Jul 18 18:43:58 2013 -0400
    28.3 @@ -35,7 +35,7 @@
    28.4   * Attempts to mostly mirror the POSIX style IO functions.
    28.5   */
    28.6  
    28.7 -typedef FILE LLFILE;
    28.8 +typedef FILE	LLFILE;
    28.9  
   28.10  #include <fstream>
   28.11  #include <sys/stat.h>
   28.12 @@ -237,7 +237,7 @@
   28.13  			ios_base::openmode _Mode = ios_base::in,
   28.14  			//size_t _Size = static_cast<size_t>(BUFSIZ));
   28.15  			size_t _Size = static_cast<size_t>(1));
   28.16 -
   28.17 +	
   28.18  	/**
   28.19  	 *  @brief  Create a stream using an open file descriptor.
   28.20  	 *  @param  fd    An open file descriptor.
    29.1 --- a/indra/llcommon/llsdserialize_xml.cpp	Thu Jul 18 15:14:55 2013 -0400
    29.2 +++ b/indra/llcommon/llsdserialize_xml.cpp	Thu Jul 18 18:43:58 2013 -0400
    29.3 @@ -406,7 +406,7 @@
    29.4  		}
    29.5  		if (mEmitErrors)
    29.6  		{
    29.7 -			llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl;
    29.8 +		llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl;
    29.9  		}
   29.10  		data = LLSD();
   29.11  		return LLSDParser::PARSE_FAILURE;
   29.12 @@ -487,7 +487,7 @@
   29.13  	{
   29.14  		if (mEmitErrors)
   29.15  		{
   29.16 -			llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl;
   29.17 +		llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl;
   29.18  		}
   29.19  		return LLSDParser::PARSE_FAILURE;
   29.20  	}
    30.1 --- a/indra/llcommon/tests/llprocess_test.cpp	Thu Jul 18 15:14:55 2013 -0400
    30.2 +++ b/indra/llcommon/tests/llprocess_test.cpp	Thu Jul 18 18:43:58 2013 -0400
    30.3 @@ -969,10 +969,7 @@
    30.4                        childout.getline(), "ok");
    30.5          // important to get the implicit flush from std::endl
    30.6          py.mPy->getWritePipe().get_ostream() << "go" << std::endl;
    30.7 -        for (i = 0; i < timeout && py.mPy->isRunning() && ! childout.contains("\n"); ++i)
    30.8 -        {
    30.9 -            yield();
   30.10 -        }
   30.11 +        waitfor(*py.mPy);
   30.12          ensure("script never replied", childout.contains("\n"));
   30.13          ensure_equals("child didn't ack", childout.getline(), "ack");
   30.14          ensure_equals("bad child termination", py.mPy->getStatus().mState, LLProcess::EXITED);
    31.1 --- a/indra/llmath/llvector4a.h	Thu Jul 18 15:14:55 2013 -0400
    31.2 +++ b/indra/llmath/llvector4a.h	Thu Jul 18 18:43:58 2013 -0400
    31.3 @@ -46,6 +46,7 @@
    31.4  // of this writing, July 08, 2010) about getting it implemented before you resort to
    31.5  // LLVector3/LLVector4. 
    31.6  /////////////////////////////////
    31.7 +class LLVector4a;
    31.8  
    31.9  LL_ALIGN_PREFIX(16)
   31.10  class LLVector4a
   31.11 @@ -236,6 +237,11 @@
   31.12  	// Note that this does not consider zero length vectors!
   31.13  	inline void normalize3fast();
   31.14  
   31.15 +	// 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
   31.16 +	// Same as above except substitutes default vector contents if the vector is non-finite or degenerate due to zero length.
   31.17 +	//
   31.18 +	inline void normalize3fast_checked(LLVector4a* d = 0);
   31.19 +
   31.20  	// Return true if this vector is normalized with respect to x,y,z up to tolerance
   31.21  	inline LLBool32 isNormalized3( F32 tolerance = 1e-3 ) const;
   31.22  
    32.1 --- a/indra/llmath/llvolume.cpp	Thu Jul 18 15:14:55 2013 -0400
    32.2 +++ b/indra/llmath/llvolume.cpp	Thu Jul 18 18:43:58 2013 -0400
    32.3 @@ -1392,7 +1392,7 @@
    32.4  	pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t);
    32.5  	pt->mScale.mV[VY] = hole_y * lerp(taper_y_begin, taper_y_end, t);
    32.6  	pt->mTexT  = t;
    32.7 -	
    32.8 +
    32.9  	// Twist rotates the path along the x,y plane (I think) - DJS 04/05/02
   32.10  	twist.setQuat  (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);
   32.11  	// Rotate the point around the circle's center.
   32.12 @@ -1446,7 +1446,7 @@
   32.13  	pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t);
   32.14  	pt->mScale.mV[VY] = hole_y * lerp(taper_y_begin, taper_y_end, t);
   32.15  	pt->mTexT  = t;
   32.16 -	
   32.17 +
   32.18  	// Twist rotates the path along the x,y plane (I think) - DJS 04/05/02
   32.19  	twist.setQuat  (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);
   32.20  	// Rotate the point around the circle's center.
   32.21 @@ -1594,7 +1594,7 @@
   32.22  			S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * params.getRevolutions());
   32.23  
   32.24  			if (is_sculpted)
   32.25 -				sides = sculpt_size;
   32.26 +				sides = llmax(sculpt_size, 1);
   32.27  			
   32.28  			genNGon(params, sides);
   32.29  		}
   32.30 @@ -1644,6 +1644,7 @@
   32.31  			mPath[i].mScale.mV[0] = lerp(1,params.getScale().mV[0],t);
   32.32  			mPath[i].mScale.mV[1] = lerp(1,params.getScale().mV[1],t);
   32.33  			mPath[i].mTexT  = t;
   32.34 +
   32.35  			mPath[i].mRot.setQuat(F_PI * params.getTwist() * t,1,0,0);
   32.36  		}
   32.37  
   32.38 @@ -2079,9 +2080,9 @@
   32.39  	createVolumeFaces();
   32.40  }
   32.41  
   32.42 -void LLVolume::genBinormals(S32 face)
   32.43 -{
   32.44 -	mVolumeFaces[face].createBinormals();
   32.45 +void LLVolume::genTangents(S32 face)
   32.46 +{
   32.47 +	mVolumeFaces[face].createTangents();
   32.48  }
   32.49  
   32.50  LLVolume::~LLVolume()
   32.51 @@ -2442,6 +2443,7 @@
   32.52  			LLVector4a pos_range;
   32.53  			pos_range.setSub(max_pos, min_pos);
   32.54  			LLVector2 tc_range2 = max_tc - min_tc;
   32.55 +
   32.56  			LLVector4a tc_range;
   32.57  			tc_range.set(tc_range2[0], tc_range2[1], tc_range2[0], tc_range2[1]);
   32.58  			LLVector4a min_tc4(min_tc[0], min_tc[1], min_tc[0], min_tc[1]);
   32.59 @@ -4392,7 +4394,7 @@
   32.60  				segments.push_back(vertices.size());
   32.61  #if DEBUG_SILHOUETTE_BINORMALS
   32.62  				vertices.push_back(face.mVertices[j].getPosition());
   32.63 -				vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mBinormal*0.1f);
   32.64 +				vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mTangent*0.1f);
   32.65  				normals.push_back(LLVector3(0,0,1));
   32.66  				normals.push_back(LLVector3(0,0,1));
   32.67  				segments.push_back(vertices.size());
   32.68 @@ -4508,22 +4510,9 @@
   32.69  	}
   32.70  }
   32.71  
   32.72 -S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, 
   32.73 -								   S32 face,
   32.74 -								   LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
   32.75 -{
   32.76 -	LLVector4a starta, enda;
   32.77 -	starta.load3(start.mV);
   32.78 -	enda.load3(end.mV);
   32.79 -
   32.80 -	return lineSegmentIntersect(starta, enda, face, intersection, tex_coord, normal, bi_normal);
   32.81 -
   32.82 -}
   32.83 -
   32.84 -
   32.85  S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, 
   32.86  								   S32 face,
   32.87 -								   LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
   32.88 +								   LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent_out)
   32.89  {
   32.90  	S32 hit_face = -1;
   32.91  	
   32.92 @@ -4561,9 +4550,9 @@
   32.93  
   32.94          if (LLLineSegmentBoxIntersect(start, end, box_center, box_size))
   32.95  		{
   32.96 -			if (bi_normal != NULL) // if the caller wants binormals, we may need to generate them
   32.97 +			if (tangent_out != NULL) // if the caller wants tangents, we may need to generate them
   32.98  			{
   32.99 -				genBinormals(i);
  32.100 +				genTangents(i);
  32.101  			}
  32.102  
  32.103  			if (isUnique())
  32.104 @@ -4597,7 +4586,7 @@
  32.105  								LLVector4a intersect = dir;
  32.106  								intersect.mul(closest_t);
  32.107  								intersect.add(start);
  32.108 -								intersection->set(intersect.getF32ptr());
  32.109 +								*intersection = intersect;
  32.110  							}
  32.111  
  32.112  
  32.113 @@ -4612,19 +4601,42 @@
  32.114  
  32.115  							if (normal!= NULL)
  32.116  							{
  32.117 -								LLVector4* norm = (LLVector4*) face.mNormals;
  32.118 -
  32.119 -								*normal		= ((1.f - a - b)  * LLVector3(norm[idx0]) + 
  32.120 -									a              * LLVector3(norm[idx1]) +
  32.121 -									b              * LLVector3(norm[idx2]));
  32.122 +								LLVector4a* norm = face.mNormals;
  32.123 +								
  32.124 +								LLVector4a n1,n2,n3;
  32.125 +								n1 = norm[idx0];
  32.126 +								n1.mul(1.f-a-b);
  32.127 +								
  32.128 +								n2 = norm[idx1];
  32.129 +								n2.mul(a);
  32.130 +								
  32.131 +								n3 = norm[idx2];
  32.132 +								n3.mul(b);
  32.133 +
  32.134 +								n1.add(n2);
  32.135 +								n1.add(n3);
  32.136 +								
  32.137 +								*normal		= n1; 
  32.138  							}
  32.139  
  32.140 -							if (bi_normal != NULL)
  32.141 +							if (tangent_out != NULL)
  32.142  							{
  32.143 -								LLVector4* binormal = (LLVector4*) face.mBinormals;
  32.144 -								*bi_normal = ((1.f - a - b)  * LLVector3(binormal[idx0]) + 
  32.145 -										a              * LLVector3(binormal[idx1]) +
  32.146 -										b              * LLVector3(binormal[idx2]));
  32.147 +								LLVector4a* tangents = face.mTangents;
  32.148 +								
  32.149 +								LLVector4a t1,t2,t3;
  32.150 +								t1 = tangents[idx0];
  32.151 +								t1.mul(1.f-a-b);
  32.152 +								
  32.153 +								t2 = tangents[idx1];
  32.154 +								t2.mul(a);
  32.155 +								
  32.156 +								t3 = tangents[idx2];
  32.157 +								t3.mul(b);
  32.158 +
  32.159 +								t1.add(t2);
  32.160 +								t1.add(t3);
  32.161 +								
  32.162 +								*tangent_out = t1; 
  32.163  							}
  32.164  						}
  32.165  					}
  32.166 @@ -4637,7 +4649,7 @@
  32.167  					face.createOctree();
  32.168  				}
  32.169  			
  32.170 -				LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal);
  32.171 +				LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out);
  32.172  				intersect.traverse(face.mOctree);
  32.173  				if (intersect.mHitFace)
  32.174  				{
  32.175 @@ -5183,7 +5195,7 @@
  32.176  	mNumIndices(0),
  32.177  	mPositions(NULL),
  32.178  	mNormals(NULL),
  32.179 -	mBinormals(NULL),
  32.180 +	mTangents(NULL),
  32.181  	mTexCoords(NULL),
  32.182  	mIndices(NULL),
  32.183  	mWeights(NULL),
  32.184 @@ -5206,7 +5218,7 @@
  32.185  	mNumIndices(0),
  32.186  	mPositions(NULL),
  32.187  	mNormals(NULL),
  32.188 -	mBinormals(NULL),
  32.189 +	mTangents(NULL),
  32.190  	mTexCoords(NULL),
  32.191  	mIndices(NULL),
  32.192  	mWeights(NULL),
  32.193 @@ -5264,15 +5276,15 @@
  32.194  		}
  32.195  
  32.196  
  32.197 -		if (src.mBinormals)
  32.198 -		{
  32.199 -			allocateBinormals(src.mNumVertices);
  32.200 -			LLVector4a::memcpyNonAliased16((F32*) mBinormals, (F32*) src.mBinormals, vert_size);
  32.201 +		if (src.mTangents)
  32.202 +		{
  32.203 +			allocateTangents(src.mNumVertices);
  32.204 +			LLVector4a::memcpyNonAliased16((F32*) mTangents, (F32*) src.mTangents, vert_size);
  32.205  		}
  32.206  		else
  32.207  		{
  32.208 -			ll_aligned_free_16(mBinormals);
  32.209 -			mBinormals = NULL;
  32.210 +			ll_aligned_free_16(mTangents);
  32.211 +			mTangents = NULL;
  32.212  		}
  32.213  
  32.214  		if (src.mWeights)
  32.215 @@ -5316,8 +5328,8 @@
  32.216  	mTexCoords = NULL;
  32.217  	ll_aligned_free_16(mIndices);
  32.218  	mIndices = NULL;
  32.219 -	ll_aligned_free_16(mBinormals);
  32.220 -	mBinormals = NULL;
  32.221 +	ll_aligned_free_16(mTangents);
  32.222 +	mTangents = NULL;
  32.223  	ll_aligned_free_16(mWeights);
  32.224  	mWeights = NULL;
  32.225  
  32.226 @@ -5897,7 +5909,7 @@
  32.227  	}
  32.228  
  32.229  	LLVector4a* binorm = NULL;
  32.230 -	if (mBinormals)
  32.231 +	if (mTangents)
  32.232  	{
  32.233  		binorm = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
  32.234  	}
  32.235 @@ -5922,9 +5934,9 @@
  32.236  			{
  32.237  				wght[cur_idx] = mWeights[idx];
  32.238  			}
  32.239 -			if (mBinormals)
  32.240 +			if (mTangents)
  32.241  			{
  32.242 -				binorm[cur_idx] = mBinormals[idx];
  32.243 +				binorm[cur_idx] = mTangents[idx];
  32.244  			}
  32.245  
  32.246  			cur_idx++;
  32.247 @@ -5940,13 +5952,13 @@
  32.248  	ll_aligned_free_16(mNormals);
  32.249  	ll_aligned_free_16(mTexCoords);
  32.250  	ll_aligned_free_16(mWeights);
  32.251 -	ll_aligned_free_16(mBinormals);
  32.252 +	ll_aligned_free_16(mTangents);
  32.253  
  32.254  	mPositions = pos;
  32.255  	mNormals = norm;
  32.256  	mTexCoords = tc;
  32.257  	mWeights = wght;
  32.258 -	mBinormals = binorm;
  32.259 +	mTangents = binorm;
  32.260  
  32.261  	//std::string result = llformat("ACMR pre/post: %.3f/%.3f  --  %d triangles %d breaks", pre_acmr, post_acmr, mNumIndices/3, breaks);
  32.262  	//llinfos << result << llendl;
  32.263 @@ -6027,7 +6039,7 @@
  32.264  {
  32.265  	llswap(rhs.mPositions, mPositions);
  32.266  	llswap(rhs.mNormals, mNormals);
  32.267 -	llswap(rhs.mBinormals, mBinormals);
  32.268 +	llswap(rhs.mTangents, mTangents);
  32.269  	llswap(rhs.mTexCoords, mTexCoords);
  32.270  	llswap(rhs.mIndices,mIndices);
  32.271  	llswap(rhs.mNumVertices, mNumVertices);
  32.272 @@ -6116,22 +6128,11 @@
  32.273  			corners[2].mTexCoord=swap;
  32.274  		}
  32.275  
  32.276 -		LLVector4a binormal;
  32.277 -		
  32.278 -		calc_binormal_from_triangle( binormal,
  32.279 -			corners[0].getPosition(), corners[0].mTexCoord,
  32.280 -			corners[1].getPosition(), corners[1].mTexCoord,
  32.281 -			corners[2].getPosition(), corners[2].mTexCoord);
  32.282 -		
  32.283 -		binormal.normalize3fast();
  32.284 -
  32.285  		S32 size = (grid_size+1)*(grid_size+1);
  32.286  		resizeVertices(size);
  32.287 -		allocateBinormals(size);
  32.288 -
  32.289 +		
  32.290  		LLVector4a* pos = (LLVector4a*) mPositions;
  32.291  		LLVector4a* norm = (LLVector4a*) mNormals;
  32.292 -		LLVector4a* binorm = (LLVector4a*) mBinormals;
  32.293  		LLVector2* tc = (LLVector2*) mTexCoords;
  32.294  
  32.295  		for(int gx = 0;gx<grid_size+1;gx++)
  32.296 @@ -6150,8 +6151,7 @@
  32.297  				*pos++ = newVert.getPosition();
  32.298  				*norm++ = baseVert.getNormal();
  32.299  				*tc++ = newVert.mTexCoord;
  32.300 -				*binorm++ = binormal;
  32.301 -
  32.302 +				
  32.303  				if (gx == 0 && gy == 0)
  32.304  				{
  32.305  					min = newVert.getPosition();
  32.306 @@ -6227,8 +6227,7 @@
  32.307  	if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK))
  32.308  	{
  32.309  		resizeVertices(num_vertices+1);
  32.310 -		allocateBinormals(num_vertices+1);	
  32.311 -
  32.312 +		
  32.313  		if (!partial_build)
  32.314  		{
  32.315  			resizeIndices(num_indices+3);
  32.316 @@ -6237,8 +6236,7 @@
  32.317  	else
  32.318  	{
  32.319  		resizeVertices(num_vertices);
  32.320 -		allocateBinormals(num_vertices);
  32.321 -
  32.322 +		
  32.323  		if (!partial_build)
  32.324  		{
  32.325  			resizeIndices(num_indices);
  32.326 @@ -6272,8 +6270,7 @@
  32.327  	LLVector2* tc = (LLVector2*) mTexCoords;
  32.328  	LLVector4a* pos = (LLVector4a*) mPositions;
  32.329  	LLVector4a* norm = (LLVector4a*) mNormals;
  32.330 -	LLVector4a* binorm = (LLVector4a*) mBinormals;
  32.331 -
  32.332 +	
  32.333  	// Copy the vertices into the array
  32.334  	for (S32 i = 0; i < num_vertices; i++)
  32.335  	{
  32.336 @@ -6309,31 +6306,6 @@
  32.337  
  32.338  	cuv = (min_uv + max_uv)*0.5f;
  32.339  
  32.340 -	LLVector4a binormal;
  32.341 -	calc_binormal_from_triangle(binormal,
  32.342 -		*mCenter, cuv,
  32.343 -		pos[0], tc[0],
  32.344 -		pos[1], tc[1]);
  32.345 -	binormal.normalize3fast();
  32.346 -
  32.347 -	LLVector4a normal;
  32.348 -	LLVector4a d0, d1;
  32.349 -	
  32.350 -
  32.351 -	d0.setSub(*mCenter, pos[0]);
  32.352 -	d1.setSub(*mCenter, pos[1]);
  32.353 -
  32.354 -	if (mTypeMask & TOP_MASK)
  32.355 -	{
  32.356 -		normal.setCross3(d0, d1);
  32.357 -	}
  32.358 -	else
  32.359 -	{
  32.360 -		normal.setCross3(d1, d0);
  32.361 -	}
  32.362 -
  32.363 -	normal.normalize3fast();
  32.364 -
  32.365  	VertexData vd;
  32.366  	vd.setPosition(*mCenter);
  32.367  	vd.mTexCoord = cuv;
  32.368 @@ -6342,15 +6314,10 @@
  32.369  	{
  32.370  		pos[num_vertices] = *mCenter;
  32.371  		tc[num_vertices] = cuv;
  32.372 +
  32.373  		num_vertices++;
  32.374  	}
  32.375  		
  32.376 -	for (S32 i = 0; i < num_vertices; i++)
  32.377 -	{
  32.378 -		binorm[i].load4a(binormal.getF32ptr());
  32.379 -		norm[i].load4a(normal.getF32ptr());
  32.380 -	}
  32.381 -
  32.382  	if (partial_build)
  32.383  	{
  32.384  		return TRUE;
  32.385 @@ -6585,63 +6552,68 @@
  32.386  
  32.387  
  32.388  	}
  32.389 -		
  32.390 +
  32.391 +	LLVector4a d0,d1;
  32.392 +
  32.393 +	d0.setSub(mPositions[mIndices[1]], mPositions[mIndices[0]]);
  32.394 +	d1.setSub(mPositions[mIndices[2]], mPositions[mIndices[0]]);
  32.395 +
  32.396 +	LLVector4a normal;
  32.397 +	normal.setCross3(d0,d1);
  32.398 +
  32.399 +	if (normal.dot3(normal).getF32() > F_APPROXIMATELY_ZERO)
  32.400 +	{
  32.401 +		normal.normalize3fast();
  32.402 +	}
  32.403 +	else
  32.404 +	{ //degenerate, make up a value
  32.405 +		normal.set(0,0,1);
  32.406 +	}
  32.407 +
  32.408 +	llassert(llfinite(normal.getF32ptr()[0]));
  32.409 +	llassert(llfinite(normal.getF32ptr()[1]));
  32.410 +	llassert(llfinite(normal.getF32ptr()[2]));
  32.411 +
  32.412 +	llassert(!llisnan(normal.getF32ptr()[0]));
  32.413 +	llassert(!llisnan(normal.getF32ptr()[1]));
  32.414 +	llassert(!llisnan(normal.getF32ptr()[2]));
  32.415 +	
  32.416 +	for (S32 i = 0; i < num_vertices; i++)
  32.417 +	{
  32.418 +		norm[i].load4a(normal.getF32ptr());
  32.419 +	}
  32.420 +
  32.421  	return TRUE;
  32.422  }
  32.423  
  32.424 -void LLVolumeFace::createBinormals()
  32.425 -{
  32.426 -	if (!mBinormals)
  32.427 -	{
  32.428 -		allocateBinormals(mNumVertices);
  32.429 -
  32.430 -		//generate binormals
  32.431 -		LLVector4a* pos = mPositions;
  32.432 -		LLVector2* tc = (LLVector2*) mTexCoords;
  32.433 -		LLVector4a* binorm = (LLVector4a*) mBinormals;
  32.434 -
  32.435 -		LLVector4a* end = mBinormals+mNumVertices;
  32.436 +void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,
  32.437 +        const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent);
  32.438 +
  32.439 +void LLVolumeFace::createTangents()
  32.440 +{
  32.441 +	if (!mTangents)
  32.442 +	{
  32.443 +		allocateTangents(mNumVertices);
  32.444 +
  32.445 +		//generate tangents
  32.446 +		//LLVector4a* pos = mPositions;
  32.447 +		//LLVector2* tc = (LLVector2*) mTexCoords;
  32.448 +		LLVector4a* binorm = (LLVector4a*) mTangents;
  32.449 +
  32.450 +		LLVector4a* end = mTangents+mNumVertices;
  32.451  		while (binorm < end)
  32.452  		{
  32.453  			(*binorm++).clear();
  32.454  		}
  32.455  
  32.456 -		binorm = mBinormals;
  32.457 -
  32.458 -		for (U32 i = 0; i < mNumIndices/3; i++) 
  32.459 -		{	//for each triangle
  32.460 -			const U16& i0 = mIndices[i*3+0];
  32.461 -			const U16& i1 = mIndices[i*3+1];
  32.462 -			const U16& i2 = mIndices[i*3+2];
  32.463 -						
  32.464 -			//calculate binormal
  32.465 -			LLVector4a binormal;
  32.466 -			calc_binormal_from_triangle(binormal,
  32.467 -										pos[i0], tc[i0],
  32.468 -										pos[i1], tc[i1],
  32.469 -										pos[i2], tc[i2]);
  32.470 -
  32.471 -
  32.472 -			//add triangle normal to vertices
  32.473 -			binorm[i0].add(binormal);
  32.474 -			binorm[i1].add(binormal);
  32.475 -			binorm[i2].add(binormal);
  32.476 -
  32.477 -			//even out quad contributions
  32.478 -			if (i % 2 == 0) 
  32.479 -			{
  32.480 -				binorm[i2].add(binormal);
  32.481 -			}
  32.482 -			else 
  32.483 -			{
  32.484 -				binorm[i1].add(binormal);
  32.485 -			}
  32.486 -		}
  32.487 -
  32.488 -		//normalize binormals
  32.489 +		binorm = mTangents;
  32.490 +
  32.491 +		CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices/3, mIndices, mTangents);
  32.492 +
  32.493 +		//normalize tangents
  32.494  		for (U32 i = 0; i < mNumVertices; i++) 
  32.495  		{
  32.496 -			binorm[i].normalize3fast();
  32.497 +			//binorm[i].normalize3fast();
  32.498  			//bump map/planar projection code requires normals to be normalized
  32.499  			mNormals[i].normalize3fast();
  32.500  		}
  32.501 @@ -6652,10 +6624,10 @@
  32.502  {
  32.503  	ll_aligned_free_16(mPositions);
  32.504  	ll_aligned_free_16(mNormals);
  32.505 -	ll_aligned_free_16(mBinormals);
  32.506 +	ll_aligned_free_16(mTangents);
  32.507  	ll_aligned_free_16(mTexCoords);
  32.508  
  32.509 -	mBinormals = NULL;
  32.510 +	mTangents = NULL;
  32.511  
  32.512  	if (num_verts)
  32.513  	{
  32.514 @@ -6705,9 +6677,9 @@
  32.515  	ll_assert_aligned(mTexCoords,16);
  32.516  	
  32.517  
  32.518 -	//just clear binormals
  32.519 -	ll_aligned_free_16(mBinormals);
  32.520 -	mBinormals = NULL;
  32.521 +	//just clear tangents
  32.522 +	ll_aligned_free_16(mTangents);
  32.523 +	mTangents = NULL;
  32.524  
  32.525  	mPositions[mNumVertices] = pos;
  32.526  	mNormals[mNumVertices] = norm;
  32.527 @@ -6716,10 +6688,10 @@
  32.528  	mNumVertices++;	
  32.529  }
  32.530  
  32.531 -void LLVolumeFace::allocateBinormals(S32 num_verts)
  32.532 -{
  32.533 -	ll_aligned_free_16(mBinormals);
  32.534 -	mBinormals = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
  32.535 +void LLVolumeFace::allocateTangents(S32 num_verts)
  32.536 +{
  32.537 +	ll_aligned_free_16(mTangents);
  32.538 +	mTangents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
  32.539  }
  32.540  
  32.541  void LLVolumeFace::allocateWeights(S32 num_verts)
  32.542 @@ -6956,7 +6928,6 @@
  32.543  
  32.544  			if ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2 && s > 0)
  32.545  			{
  32.546 -
  32.547  				pos[cur_vertex].load3(mesh[i].mPos.mV);
  32.548  				tc[cur_vertex] = LLVector2(ss,tt);
  32.549  			
  32.550 @@ -6987,7 +6958,6 @@
  32.551  		}
  32.552  	}
  32.553  	
  32.554 -
  32.555  	//get bounding box for this side
  32.556  	LLVector4a& face_min = mExtents[0];
  32.557  	LLVector4a& face_max = mExtents[1];
  32.558 @@ -7093,6 +7063,14 @@
  32.559  		n[1]->add(c);
  32.560  		n[2]->add(c);
  32.561  		
  32.562 +		llassert(llfinite(c.getF32ptr()[0]));
  32.563 +		llassert(llfinite(c.getF32ptr()[1]));
  32.564 +		llassert(llfinite(c.getF32ptr()[2]));
  32.565 +
  32.566 +		llassert(!llisnan(c.getF32ptr()[0]));
  32.567 +		llassert(!llisnan(c.getF32ptr()[1]));
  32.568 +		llassert(!llisnan(c.getF32ptr()[2]));
  32.569 +
  32.570  		//even out quad contributions
  32.571  		n[i%2+1]->add(c);
  32.572  	}
  32.573 @@ -7231,53 +7209,101 @@
  32.574  	return TRUE;
  32.575  }
  32.576  
  32.577 -// Finds binormal based on three vertices with texture coordinates.
  32.578 -// Fills in dummy values if the triangle has degenerate texture coordinates.
  32.579 -void calc_binormal_from_triangle(LLVector4a& binormal,
  32.580 -
  32.581 -	const LLVector4a& pos0,
  32.582 -	const LLVector2& tex0,
  32.583 -	const LLVector4a& pos1,
  32.584 -	const LLVector2& tex1,
  32.585 -	const LLVector4a& pos2,
  32.586 -	const LLVector2& tex2)
  32.587 -{
  32.588 -	LLVector4a rx0( pos0[VX], tex0.mV[VX], tex0.mV[VY] );
  32.589 -	LLVector4a rx1( pos1[VX], tex1.mV[VX], tex1.mV[VY] );
  32.590 -	LLVector4a rx2( pos2[VX], tex2.mV[VX], tex2.mV[VY] );
  32.591 -	
  32.592 -	LLVector4a ry0( pos0[VY], tex0.mV[VX], tex0.mV[VY] );
  32.593 -	LLVector4a ry1( pos1[VY], tex1.mV[VX], tex1.mV[VY] );
  32.594 -	LLVector4a ry2( pos2[VY], tex2.mV[VX], tex2.mV[VY] );
  32.595 -
  32.596 -	LLVector4a rz0( pos0[VZ], tex0.mV[VX], tex0.mV[VY] );
  32.597 -	LLVector4a rz1( pos1[VZ], tex1.mV[VX], tex1.mV[VY] );
  32.598 -	LLVector4a rz2( pos2[VZ], tex2.mV[VX], tex2.mV[VY] );
  32.599 -	
  32.600 -	LLVector4a lhs, rhs;
  32.601 -
  32.602 -	LLVector4a r0; 
  32.603 -	lhs.setSub(rx0, rx1); rhs.setSub(rx0, rx2);
  32.604 -	r0.setCross3(lhs, rhs);
  32.605 +//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
  32.606 +void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,
  32.607 +        const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent)
  32.608 +{
  32.609 +    //LLVector4a *tan1 = new LLVector4a[vertexCount * 2];
  32.610 +	LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a));
  32.611 +
  32.612 +    LLVector4a* tan2 = tan1 + vertexCount;
  32.613 +
  32.614 +	memset(tan1, 0, vertexCount*2*sizeof(LLVector4a));
  32.615 +        
  32.616 +    for (U32 a = 0; a < triangleCount; a++)
  32.617 +    {
  32.618 +        U32 i1 = *index_array++;
  32.619 +        U32 i2 = *index_array++;
  32.620 +        U32 i3 = *index_array++;
  32.621 +        
  32.622 +        const LLVector4a& v1 = vertex[i1];
  32.623 +        const LLVector4a& v2 = vertex[i2];
  32.624 +        const LLVector4a& v3 = vertex[i3];
  32.625 +        
  32.626 +        const LLVector2& w1 = texcoord[i1];
  32.627 +        const LLVector2& w2 = texcoord[i2];
  32.628 +        const LLVector2& w3 = texcoord[i3];
  32.629 +        
  32.630 +		const F32* v1ptr = v1.getF32ptr();
  32.631 +		const F32* v2ptr = v2.getF32ptr();
  32.632 +		const F32* v3ptr = v3.getF32ptr();
  32.633  		
  32.634 -	LLVector4a r1;
  32.635 -	lhs.setSub(ry0, ry1); rhs.setSub(ry0, ry2);
  32.636 -	r1.setCross3(lhs, rhs);
  32.637 -
  32.638 -	LLVector4a r2;
  32.639 -	lhs.setSub(rz0, rz1); rhs.setSub(rz0, rz2);
  32.640 -	r2.setCross3(lhs, rhs);
  32.641 -
  32.642 -	if( r0[VX] && r1[VX] && r2[VX] )
  32.643 -	{
  32.644 -		binormal.set(
  32.645 -				-r0[VZ] / r0[VX],
  32.646 -				-r1[VZ] / r1[VX],
  32.647 -				-r2[VZ] / r2[VX]);
  32.648 -		// binormal.normVec();
  32.649 -	}
  32.650 -	else
  32.651 -	{
  32.652 -		binormal.set( 0, 1 , 0 );
  32.653 -	}
  32.654 -}
  32.655 +        float x1 = v2ptr[0] - v1ptr[0];
  32.656 +        float x2 = v3ptr[0] - v1ptr[0];
  32.657 +        float y1 = v2ptr[1] - v1ptr[1];
  32.658 +        float y2 = v3ptr[1] - v1ptr[1];
  32.659 +        float z1 = v2ptr[2] - v1ptr[2];
  32.660 +        float z2 = v3ptr[2] - v1ptr[2];
  32.661 +        
  32.662 +        float s1 = w2.mV[0] - w1.mV[0];
  32.663 +        float s2 = w3.mV[0] - w1.mV[0];
  32.664 +        float t1 = w2.mV[1] - w1.mV[1];
  32.665 +        float t2 = w3.mV[1] - w1.mV[1];
  32.666 +        
  32.667 +		F32 rd = s1*t2-s2*t1;
  32.668 +
  32.669 +		float r = ((rd*rd) > FLT_EPSILON) ? 1.0F / rd : 1024.f; //some made up large ratio for division by zero
  32.670 +
  32.671 +		llassert(llfinite(r));
  32.672 +		llassert(!llisnan(r));
  32.673 +
  32.674 +		LLVector4a sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
  32.675 +				(t2 * z1 - t1 * z2) * r);
  32.676 +		LLVector4a tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
  32.677 +				(s1 * z2 - s2 * z1) * r);
  32.678 +        
  32.679 +		tan1[i1].add(sdir);
  32.680 +		tan1[i2].add(sdir);
  32.681 +		tan1[i3].add(sdir);
  32.682 +        
  32.683 +		tan2[i1].add(tdir);
  32.684 +		tan2[i2].add(tdir);
  32.685 +		tan2[i3].add(tdir);
  32.686 +    }
  32.687 +    
  32.688 +    for (U32 a = 0; a < vertexCount; a++)
  32.689 +    {
  32.690 +        LLVector4a n = normal[a];
  32.691 +
  32.692 +		const LLVector4a& t = tan1[a];
  32.693 +
  32.694 +		LLVector4a ncrosst;
  32.695 +		ncrosst.setCross3(n,t);
  32.696 +
  32.697 +        // Gram-Schmidt orthogonalize
  32.698 +        n.mul(n.dot3(t).getF32());
  32.699 +
  32.700 +		LLVector4a tsubn;
  32.701 +		tsubn.setSub(t,n);
  32.702 +
  32.703 +		if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO)
  32.704 +		{
  32.705 +			tsubn.normalize3fast();
  32.706 +		
  32.707 +			// Calculate handedness
  32.708 +			F32 handedness = ncrosst.dot3(tan2[a]).getF32() < 0.f ? -1.f : 1.f;
  32.709 +		
  32.710 +			tsubn.getF32ptr()[3] = handedness;
  32.711 +
  32.712 +			tangent[a] = tsubn;
  32.713 +		}
  32.714 +		else
  32.715 +		{ //degenerate, make up a value
  32.716 +			tangent[a].set(0,0,1,1);
  32.717 +		}
  32.718 +    }
  32.719 +    
  32.720 +	ll_aligned_free_16(tan1);
  32.721 +}
  32.722 +
  32.723 +
    33.1 --- a/indra/llmath/llvolume.h	Thu Jul 18 15:14:55 2013 -0400
    33.2 +++ b/indra/llmath/llvolume.h	Thu Jul 18 18:43:58 2013 -0400
    33.3 @@ -844,12 +844,12 @@
    33.4  public:
    33.5  
    33.6  	BOOL create(LLVolume* volume, BOOL partial_build = FALSE);
    33.7 -	void createBinormals();
    33.8 +	void createTangents();
    33.9  	
   33.10  	void appendFace(const LLVolumeFace& face, LLMatrix4& transform, LLMatrix4& normal_tranform);
   33.11  
   33.12  	void resizeVertices(S32 num_verts);
   33.13 -	void allocateBinormals(S32 num_verts);
   33.14 +	void allocateTangents(S32 num_verts);
   33.15  	void allocateWeights(S32 num_verts);
   33.16  	void resizeIndices(S32 num_indices);
   33.17  	void fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v, std::vector<U16>& idx);
   33.18 @@ -916,7 +916,7 @@
   33.19  
   33.20  	LLVector4a* mPositions;
   33.21  	LLVector4a* mNormals;
   33.22 -	LLVector4a* mBinormals;
   33.23 +	LLVector4a* mTangents;
   33.24  	LLVector2*  mTexCoords;
   33.25  	U16* mIndices;
   33.26  
   33.27 @@ -980,7 +980,7 @@
   33.28  	void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); }
   33.29  
   33.30  	void regen();
   33.31 -	void genBinormals(S32 face);
   33.32 +	void genTangents(S32 face);
   33.33  
   33.34  	BOOL isConvex() const;
   33.35  	BOOL isCap(S32 face);
   33.36 @@ -1008,21 +1008,14 @@
   33.37  	//get the face index of the face that intersects with the given line segment at the point 
   33.38  	//closest to start.  Moves end to the point of intersection.  Returns -1 if no intersection.
   33.39  	//Line segment must be in volume space.
   33.40 -	S32 lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
   33.41 +	S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
   33.42  							 S32 face = -1,                          // which face to check, -1 = ALL_SIDES
   33.43 -							 LLVector3* intersection = NULL,         // return the intersection point
   33.44 +							 LLVector4a* intersection = NULL,         // return the intersection point
   33.45  							 LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point
   33.46 -							 LLVector3* normal = NULL,               // return the surface normal at the intersection point
   33.47 -							 LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point
   33.48 +							 LLVector4a* normal = NULL,               // return the surface normal at the intersection point
   33.49 +							 LLVector4a* tangent = NULL             // return the surface tangent at the intersection point
   33.50  		);
   33.51  
   33.52 -	S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, 
   33.53 -								   S32 face = 1,
   33.54 -								   LLVector3* intersection = NULL,
   33.55 -								   LLVector2* tex_coord = NULL,
   33.56 -								   LLVector3* normal = NULL,
   33.57 -								   LLVector3* bi_normal = NULL);
   33.58 -	
   33.59  	LLFaceID generateFaceMask();
   33.60  
   33.61  	BOOL isFaceMaskValid(LLFaceID face_mask);
   33.62 @@ -1081,21 +1074,12 @@
   33.63  
   33.64  std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params);
   33.65  
   33.66 -void calc_binormal_from_triangle(
   33.67 -		LLVector4a& binormal,
   33.68 -		const LLVector4a& pos0,
   33.69 -		const LLVector2& tex0,
   33.70 -		const LLVector4a& pos1,
   33.71 -		const LLVector2& tex1,
   33.72 -		const LLVector4a& pos2,
   33.73 -		const LLVector2& tex2);
   33.74 -
   33.75  BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size);
   33.76  BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size);
   33.77  BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size);
   33.78  
   33.79 -BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir,
   33.80 -							F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided);
   33.81 +//BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir,
   33.82 +//							F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided);
   33.83  
   33.84  BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir,
   33.85  							F32& intersection_a, F32& intersection_b, F32& intersection_t);
    34.1 --- a/indra/llmath/llvolumeoctree.cpp	Thu Jul 18 15:14:55 2013 -0400
    34.2 +++ b/indra/llmath/llvolumeoctree.cpp	Thu Jul 18 18:43:58 2013 -0400
    34.3 @@ -94,14 +94,14 @@
    34.4  
    34.5  LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir, 
    34.6  							   const LLVolumeFace* face, F32* closest_t,
    34.7 -							   LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
    34.8 +							   LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
    34.9     : mFace(face),
   34.10       mStart(start),
   34.11  	 mDir(dir),
   34.12  	 mIntersection(intersection),
   34.13  	 mTexCoord(tex_coord),
   34.14  	 mNormal(normal),
   34.15 -	 mBinormal(bi_normal),
   34.16 +	 mTangent(tangent),
   34.17  	 mClosestT(closest_t),
   34.18  	 mHitFace(false)
   34.19  {
   34.20 @@ -112,13 +112,7 @@
   34.21  {
   34.22  	LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0);
   34.23  
   34.24 -	/*const F32* start = mStart.getF32();
   34.25 -	const F32* end = mEnd.getF32();
   34.26 -	const F32* center = vl->mBounds[0].getF32();
   34.27 -	const F32* size = vl->mBounds[1].getF32();*/
   34.28 -
   34.29 -	//if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1]))
   34.30 -	if (LLLineSegmentBoxIntersect(mStart.getF32ptr(), mEnd.getF32ptr(), vl->mBounds[0].getF32ptr(), vl->mBounds[1].getF32ptr()))
   34.31 +	if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1]))
   34.32  	{
   34.33  		node->accept(this);
   34.34  		for (S32 i = 0; i < node->getChildCount(); ++i)
   34.35 @@ -152,34 +146,60 @@
   34.36  					LLVector4a intersect = mDir;
   34.37  					intersect.mul(*mClosestT);
   34.38  					intersect.add(mStart);
   34.39 -					mIntersection->set(intersect.getF32ptr());
   34.40 +					*mIntersection = intersect;
   34.41  				}
   34.42  
   34.43 +				U32 idx0 = tri->mIndex[0];
   34.44 +				U32 idx1 = tri->mIndex[1];
   34.45 +				U32 idx2 = tri->mIndex[2];
   34.46  
   34.47  				if (mTexCoord != NULL)
   34.48  				{
   34.49  					LLVector2* tc = (LLVector2*) mFace->mTexCoords;
   34.50 -					*mTexCoord = ((1.f - a - b)  * tc[tri->mIndex[0]] +
   34.51 -						a              * tc[tri->mIndex[1]] +
   34.52 -						b              * tc[tri->mIndex[2]]);
   34.53 +					*mTexCoord = ((1.f - a - b)  * tc[idx0] +
   34.54 +						a              * tc[idx1] +
   34.55 +						b              * tc[idx2]);
   34.56  
   34.57  				}
   34.58  
   34.59  				if (mNormal != NULL)
   34.60  				{
   34.61 -					LLVector4* norm = (LLVector4*) mFace->mNormals;
   34.62 +					LLVector4a* norm = mFace->mNormals;
   34.63 +								
   34.64 +					LLVector4a n1,n2,n3;
   34.65 +					n1 = norm[idx0];
   34.66 +					n1.mul(1.f-a-b);
   34.67 +								
   34.68 +					n2 = norm[idx1];
   34.69 +					n2.mul(a);
   34.70 +								
   34.71 +					n3 = norm[idx2];
   34.72 +					n3.mul(b);
   34.73  
   34.74 -					*mNormal    = ((1.f - a - b)  * LLVector3(norm[tri->mIndex[0]]) + 
   34.75 -						a              * LLVector3(norm[tri->mIndex[1]]) +
   34.76 -						b              * LLVector3(norm[tri->mIndex[2]]));
   34.77 +					n1.add(n2);
   34.78 +					n1.add(n3);
   34.79 +								
   34.80 +					*mNormal		= n1; 
   34.81  				}
   34.82  
   34.83 -				if (mBinormal != NULL)
   34.84 +				if (mTangent != NULL)
   34.85  				{
   34.86 -					LLVector4* binormal = (LLVector4*) mFace->mBinormals;
   34.87 -					*mBinormal = ((1.f - a - b)  * LLVector3(binormal[tri->mIndex[0]]) + 
   34.88 -							a              * LLVector3(binormal[tri->mIndex[1]]) +
   34.89 -							b              * LLVector3(binormal[tri->mIndex[2]]));
   34.90 +					LLVector4a* tangents = mFace->mTangents;
   34.91 +								
   34.92 +					LLVector4a t1,t2,t3;
   34.93 +					t1 = tangents[idx0];
   34.94 +					t1.mul(1.f-a-b);
   34.95 +								
   34.96 +					t2 = tangents[idx1];
   34.97 +					t2.mul(a);
   34.98 +								
   34.99 +					t3 = tangents[idx2];
  34.100 +					t3.mul(b);
  34.101 +
  34.102 +					t1.add(t2);
  34.103 +					t1.add(t3);
  34.104 +								
  34.105 +					*mTangent = t1; 
  34.106  				}
  34.107  			}
  34.108  		}
    35.1 --- a/indra/llmath/llvolumeoctree.h	Thu Jul 18 15:14:55 2013 -0400
    35.2 +++ b/indra/llmath/llvolumeoctree.h	Thu Jul 18 18:43:58 2013 -0400
    35.3 @@ -137,16 +137,16 @@
    35.4  	LLVector4a mStart;
    35.5  	LLVector4a mDir;
    35.6  	LLVector4a mEnd;
    35.7 -	LLVector3* mIntersection;
    35.8 +	LLVector4a* mIntersection;
    35.9  	LLVector2* mTexCoord;
   35.10 -	LLVector3* mNormal;
   35.11 -	LLVector3* mBinormal;
   35.12 +	LLVector4a* mNormal;
   35.13 +	LLVector4a* mTangent;
   35.14  	F32* mClosestT;
   35.15  	bool mHitFace;
   35.16  
   35.17  	LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir, 
   35.18  								   const LLVolumeFace* face, F32* closest_t,
   35.19 -								   LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal);
   35.20 +								   LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent);
   35.21  
   35.22  	void traverse(const LLOctreeNode<LLVolumeTriangle>* node);
   35.23  
    36.1 --- a/indra/llmessage/CMakeLists.txt	Thu Jul 18 15:14:55 2013 -0400
    36.2 +++ b/indra/llmessage/CMakeLists.txt	Thu Jul 18 18:43:58 2013 -0400
    36.3 @@ -246,7 +246,7 @@
    36.4      ${LLVFS_LIBRARIES}
    36.5      ${LLMATH_LIBRARIES}
    36.6      ${LLCOMMON_LIBRARIES}
    36.7 -    ${GOOGLEMOCK_LIBRARIES}
    36.8 +      ${GOOGLEMOCK_LIBRARIES}
    36.9      )
   36.10  
   36.11    LL_ADD_INTEGRATION_TEST(
    37.1 --- a/indra/llmessage/llares.cpp	Thu Jul 18 15:14:55 2013 -0400
    37.2 +++ b/indra/llmessage/llares.cpp	Thu Jul 18 18:43:58 2013 -0400
    37.3 @@ -99,8 +99,7 @@
    37.4  
    37.5  LLAres::LLAres() :
    37.6      chan_(NULL),
    37.7 -    mInitSuccess(false),
    37.8 -    mListener(new LLAresListener(this))
    37.9 +    mInitSuccess(false)
   37.10  {
   37.11  	if (ares_library_init( ARES_LIB_INIT_ALL ) != ARES_SUCCESS ||
   37.12  		ares_init(&chan_) != ARES_SUCCESS)
   37.13 @@ -109,6 +108,8 @@
   37.14  		return;
   37.15  	}
   37.16  
   37.17 +	mListener = boost::shared_ptr< LLAresListener >(new LLAresListener(this));
   37.18 +
   37.19  	mInitSuccess = true;
   37.20  }
   37.21  
   37.22 @@ -161,12 +162,26 @@
   37.23  }
   37.24  	
   37.25  void LLAres::rewriteURI(const std::string &uri, UriRewriteResponder *resp)
   37.26 -{
   37.27 -	llinfos << "Rewriting " << uri << llendl;
   37.28 +{	
   37.29 +	if (resp && uri.size())
   37.30 +	{
   37.31 +		LLURI* pURI = new LLURI(uri);
   37.32  
   37.33 -	resp->mUri = LLURI(uri);
   37.34 -	search("_" + resp->mUri.scheme() + "._tcp." + resp->mUri.hostName(),
   37.35 -		   RES_SRV, resp);
   37.36 +		resp->mUri = *pURI;
   37.37 +
   37.38 +		delete pURI;
   37.39 +
   37.40 +		if (!resp->mUri.scheme().size() || !resp->mUri.hostName().size())
   37.41 +		{
   37.42 +			return;
   37.43 +		}
   37.44 +
   37.45 +		//llinfos << "LLAres::rewriteURI (" << uri << ") search: '" << "_" + resp->mUri.scheme() + "._tcp." + resp->mUri.hostName() << "'" << llendl;
   37.46 +
   37.47 +		search("_" + resp->mUri.scheme() + "._tcp." + resp->mUri.hostName(), RES_SRV, resp);
   37.48 +
   37.49 +		
   37.50 +	}
   37.51  }
   37.52  
   37.53  LLQueryResponder::LLQueryResponder()
    38.1 --- a/indra/llmessage/llareslistener.cpp	Thu Jul 18 15:14:55 2013 -0400
    38.2 +++ b/indra/llmessage/llareslistener.cpp	Thu Jul 18 18:43:58 2013 -0400
    38.3 @@ -93,5 +93,12 @@
    38.4  
    38.5  void LLAresListener::rewriteURI(const LLSD& data)
    38.6  {
    38.7 -    mAres->rewriteURI(data["uri"], new UriRewriteResponder(data));
    38.8 +	if (mAres)
    38.9 +	{
   38.10 +		mAres->rewriteURI(data["uri"], new UriRewriteResponder(data));
   38.11 +	}
   38.12 +	else
   38.13 +	{
   38.14 +		llinfos << "LLAresListener::rewriteURI requested without Ares present. Ignoring: " << data << llendl;
   38.15 +	}
   38.16  }
    39.1 --- a/indra/llmessage/llhttpclient.cpp	Thu Jul 18 15:14:55 2013 -0400
    39.2 +++ b/indra/llmessage/llhttpclient.cpp	Thu Jul 18 18:43:58 2013 -0400
    39.3 @@ -224,7 +224,7 @@
    39.4  	{
    39.5  		if (responder)
    39.6  		{
    39.7 -			responder->completed(U32_MAX, "No pump", LLSD());
    39.8 +		responder->completed(U32_MAX, "No pump", LLSD());
    39.9  		}
   39.10  		delete body_injector;
   39.11  		return;
   39.12 @@ -238,9 +238,9 @@
   39.13  		{
   39.14  			responder->completed(498, "Internal Error - curl failure", LLSD());
   39.15  		}
   39.16 -		delete req;
   39.17 +		delete req ;
   39.18  		delete body_injector;
   39.19 -		return;
   39.20 +		return ;
   39.21  	}
   39.22  
   39.23  	req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req);
    40.1 --- a/indra/llmessage/llhttpclientadapter.cpp	Thu Jul 18 15:14:55 2013 -0400
    40.2 +++ b/indra/llmessage/llhttpclientadapter.cpp	Thu Jul 18 18:43:58 2013 -0400
    40.3 @@ -45,8 +45,8 @@
    40.4  	LLSD empty_pragma_header = headers;
    40.5  	if (!empty_pragma_header.has("Pragma"))
    40.6  	{
    40.7 -		// as above
    40.8 -		empty_pragma_header["Pragma"] = " ";
    40.9 +	// as above
   40.10 +	empty_pragma_header["Pragma"] = " ";
   40.11  	}
   40.12  	LLHTTPClient::get(url, responder, empty_pragma_header);
   40.13  }
    41.1 --- a/indra/llmessage/llurlrequest.cpp	Thu Jul 18 15:14:55 2013 -0400
    41.2 +++ b/indra/llmessage/llurlrequest.cpp	Thu Jul 18 18:43:58 2013 -0400
    41.3 @@ -314,11 +314,11 @@
    41.4  		 const F32 TIMEOUT_ADJUSTMENT = 2.0f;
    41.5  		 mDetail->mByteAccumulator = 0;
    41.6  		 pump->adjustTimeoutSeconds(TIMEOUT_ADJUSTMENT);
    41.7 -		 lldebugs << "LLURLRequest adjustTimeoutSeconds for request: " << mDetail->mURL << llendl;
    41.8 -		 if (mState == STATE_INITIALIZED)
    41.9 -		 {
   41.10 -			  llinfos << "LLURLRequest adjustTimeoutSeconds called during upload" << llendl;
   41.11 -		 }
   41.12 +		lldebugs << "LLURLRequest adjustTimeoutSeconds for request: " << mDetail->mURL << llendl;
   41.13 +		if (mState == STATE_INITIALIZED)
   41.14 +		{
   41.15 +			llinfos << "LLURLRequest adjustTimeoutSeconds called during upload" << llendl;
   41.16 +		}
   41.17  	}
   41.18  
   41.19  	switch(mState)
    42.1 --- a/indra/llmessage/tests/llhttpclient_test.cpp	Thu Jul 18 15:14:55 2013 -0400
    42.2 +++ b/indra/llmessage/tests/llhttpclient_test.cpp	Thu Jul 18 18:43:58 2013 -0400
    42.3 @@ -241,7 +241,7 @@
    42.4  		ensureStatusOK();
    42.5  		ensure_equals("echoed result matches", getResult(), sd);
    42.6  	}
    42.7 -		
    42.8 +
    42.9  	template<> template<>
   42.10  		void HTTPClientTestObject::test<4>()
   42.11  	{
    43.1 --- a/indra/llprimitive/CMakeLists.txt	Thu Jul 18 15:14:55 2013 -0400
    43.2 +++ b/indra/llprimitive/CMakeLists.txt	Thu Jul 18 18:43:58 2013 -0400
    43.3 @@ -24,6 +24,8 @@
    43.4      )
    43.5  
    43.6  set(llprimitive_SOURCE_FILES
    43.7 +    llmaterialid.cpp
    43.8 +    llmaterial.cpp
    43.9      llmaterialtable.cpp
   43.10      llmediaentry.cpp
   43.11      llmodel.cpp
   43.12 @@ -41,6 +43,8 @@
   43.13      CMakeLists.txt
   43.14  
   43.15      legacy_object_types.h
   43.16 +    llmaterial.h
   43.17 +    llmaterialid.h
   43.18      llmaterialtable.h
   43.19      llmediaentry.h
   43.20      llmodel.h
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/indra/llprimitive/llmaterial.cpp	Thu Jul 18 18:43:58 2013 -0400
    44.3 @@ -0,0 +1,227 @@
    44.4 +/**
    44.5 + * @file llmaterial.cpp
    44.6 + * @brief Material definition
    44.7 + *
    44.8 + * $LicenseInfo:firstyear=2006&license=viewerlgpl$
    44.9 + * Second Life Viewer Source Code
   44.10 + * Copyright (C) 2010, Linden Research, Inc.
   44.11 + * 
   44.12 + * This library is free software; you can redistribute it and/or
   44.13 + * modify it under the terms of the GNU Lesser General Public
   44.14 + * License as published by the Free Software Foundation;
   44.15 + * version 2.1 of the License only.
   44.16 + * 
   44.17 + * This library is distributed in the hope that it will be useful,
   44.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   44.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   44.20 + * Lesser General Public License for more details.
   44.21 + * 
   44.22 + * You should have received a copy of the GNU Lesser General Public
   44.23 + * License along with this library; if not, write to the Free Software
   44.24 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   44.25 + * 
   44.26 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
   44.27 + * $/LicenseInfo$
   44.28 + */
   44.29 +
   44.30 +#include "linden_common.h"
   44.31 +
   44.32 +#include "llmaterial.h"
   44.33 +
   44.34 +/**
   44.35 + * Materials cap parameters
   44.36 + */
   44.37 +#define MATERIALS_CAP_NORMAL_MAP_FIELD            "NormMap"
   44.38 +#define MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD   "NormOffsetX"
   44.39 +#define MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD   "NormOffsetY"
   44.40 +#define MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD   "NormRepeatX"
   44.41 +#define MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD   "NormRepeatY"
   44.42 +#define MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD   "NormRotation"
   44.43 +
   44.44 +#define MATERIALS_CAP_SPECULAR_MAP_FIELD          "SpecMap"
   44.45 +#define MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD "SpecOffsetX"
   44.46 +#define MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD "SpecOffsetY"
   44.47 +#define MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD "SpecRepeatX"
   44.48 +#define MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD "SpecRepeatY"
   44.49 +#define MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD "SpecRotation"
   44.50 +
   44.51 +#define MATERIALS_CAP_SPECULAR_COLOR_FIELD        "SpecColor"
   44.52 +#define MATERIALS_CAP_SPECULAR_EXP_FIELD          "SpecExp"
   44.53 +#define MATERIALS_CAP_ENV_INTENSITY_FIELD         "EnvIntensity"
   44.54 +#define MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD     "AlphaMaskCutoff"
   44.55 +#define MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD    "DiffuseAlphaMode"
   44.56 +
   44.57 +const LLColor4U LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR(255,255,255,255);
   44.58 +
   44.59 +/**
   44.60 + * Materials constants
   44.61 + */
   44.62 +
   44.63 +const F32 MATERIALS_MULTIPLIER                   = 10000.f;
   44.64 +
   44.65 +/**
   44.66 + * Helper functions
   44.67 + */
   44.68 +
   44.69 +template<typename T> T getMaterialField(const LLSD& data, const std::string& field, const LLSD::Type field_type)
   44.70 +{
   44.71 +	if ( (data.has(field)) && (field_type == data[field].type()) )
   44.72 +	{
   44.73 +		return (T)data[field];
   44.74 +	}
   44.75 +	llerrs << "Missing or mistyped field '" << field << "' in material definition" << llendl;
   44.76 +	return (T)LLSD();
   44.77 +}
   44.78 +
   44.79 +// GCC didn't like the generic form above for some reason
   44.80 +template<> LLUUID getMaterialField(const LLSD& data, const std::string& field, const LLSD::Type field_type)
   44.81 +{
   44.82 +	if ( (data.has(field)) && (field_type == data[field].type()) )
   44.83 +	{
   44.84 +		return data[field].asUUID();
   44.85 +	}
   44.86 +	llerrs << "Missing or mistyped field '" << field << "' in material definition" << llendl;
   44.87 +	return LLUUID::null;
   44.88 +}
   44.89 +
   44.90 +/**
   44.91 + * LLMaterial class
   44.92 + */
   44.93 +
   44.94 +const LLMaterial LLMaterial::null;
   44.95 +
   44.96 +LLMaterial::LLMaterial()
   44.97 +	: mNormalOffsetX(0.0f)
   44.98 +	, mNormalOffsetY(0.0f)
   44.99 +	, mNormalRepeatX(1.0f)
  44.100 +	, mNormalRepeatY(1.0f)
  44.101 +	, mNormalRotation(0.0f)
  44.102 +	, mSpecularOffsetX(0.0f)
  44.103 +	, mSpecularOffsetY(0.0f)
  44.104 +	, mSpecularRepeatX(1.0f)
  44.105 +	, mSpecularRepeatY(1.0f)
  44.106 +	, mSpecularRotation(0.0f)
  44.107 +	, mSpecularLightColor(LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR)
  44.108 +	, mSpecularLightExponent(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT)
  44.109 +	, mEnvironmentIntensity(LLMaterial::DEFAULT_ENV_INTENSITY)
  44.110 +	, mDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
  44.111 +	, mAlphaMaskCutoff(0)
  44.112 +{
  44.113 +}
  44.114 +
  44.115 +LLMaterial::LLMaterial(const LLSD& material_data)
  44.116 +{
  44.117 +	fromLLSD(material_data);
  44.118 +}
  44.119 +
  44.120 +LLSD LLMaterial::asLLSD() const
  44.121 +{
  44.122 +	LLSD material_data;
  44.123 +
  44.124 +	material_data[MATERIALS_CAP_NORMAL_MAP_FIELD] = mNormalID;
  44.125 +	material_data[MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD] = llround(mNormalOffsetX * MATERIALS_MULTIPLIER);
  44.126 +	material_data[MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD] = llround(mNormalOffsetY * MATERIALS_MULTIPLIER);
  44.127 +	material_data[MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD] = llround(mNormalRepeatX * MATERIALS_MULTIPLIER);
  44.128 +	material_data[MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD] = llround(mNormalRepeatY * MATERIALS_MULTIPLIER);
  44.129 +	material_data[MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD] = llround(mNormalRotation * MATERIALS_MULTIPLIER);
  44.130 +
  44.131 +	material_data[MATERIALS_CAP_SPECULAR_MAP_FIELD] = mSpecularID;
  44.132 +	material_data[MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD] = llround(mSpecularOffsetX * MATERIALS_MULTIPLIER);
  44.133 +	material_data[MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD] = llround(mSpecularOffsetY * MATERIALS_MULTIPLIER);
  44.134 +	material_data[MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD] = llround(mSpecularRepeatX * MATERIALS_MULTIPLIER);
  44.135 +	material_data[MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD] = llround(mSpecularRepeatY * MATERIALS_MULTIPLIER);
  44.136 +	material_data[MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD] = llround(mSpecularRotation * MATERIALS_MULTIPLIER);
  44.137 +
  44.138 +	material_data[MATERIALS_CAP_SPECULAR_COLOR_FIELD]     = mSpecularLightColor.getValue();
  44.139 +	material_data[MATERIALS_CAP_SPECULAR_EXP_FIELD]       = mSpecularLightExponent;
  44.140 +	material_data[MATERIALS_CAP_ENV_INTENSITY_FIELD]      = mEnvironmentIntensity;
  44.141 +	material_data[MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD] = mDiffuseAlphaMode;
  44.142 +	material_data[MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD]  = mAlphaMaskCutoff;
  44.143 +
  44.144 +	return material_data;
  44.145 +}
  44.146 +
  44.147 +void LLMaterial::fromLLSD(const LLSD& material_data)
  44.148 +{
  44.149 +	mNormalID = getMaterialField<LLSD::UUID>(material_data, MATERIALS_CAP_NORMAL_MAP_FIELD, LLSD::TypeUUID);
  44.150 +	mNormalOffsetX  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
  44.151 +	mNormalOffsetY  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
  44.152 +	mNormalRepeatX  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
  44.153 +	mNormalRepeatY  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
  44.154 +	mNormalRotation = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
  44.155 +
  44.156 +	mSpecularID = getMaterialField<LLSD::UUID>(material_data, MATERIALS_CAP_SPECULAR_MAP_FIELD, LLSD::TypeUUID);
  44.157 +	mSpecularOffsetX  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
  44.158 +	mSpecularOffsetY  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
  44.159 +	mSpecularRepeatX  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
  44.160 +	mSpecularRepeatY  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
  44.161 +	mSpecularRotation = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
  44.162 +
  44.163 +	mSpecularLightColor.setValue(getMaterialField<LLSD>(material_data, MATERIALS_CAP_SPECULAR_COLOR_FIELD, LLSD::TypeArray));
  44.164 +	mSpecularLightExponent = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_EXP_FIELD,       LLSD::TypeInteger);
  44.165 +	mEnvironmentIntensity  = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_ENV_INTENSITY_FIELD,      LLSD::TypeInteger);
  44.166 +	mDiffuseAlphaMode      = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD, LLSD::TypeInteger);
  44.167 +	mAlphaMaskCutoff       = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD,  LLSD::TypeInteger);
  44.168 +}
  44.169 +
  44.170 +bool LLMaterial::isNull() const
  44.171 +{
  44.172 +	return (*this == null);
  44.173 +}
  44.174 +
  44.175 +bool LLMaterial::operator == (const LLMaterial& rhs) const
  44.176 +{
  44.177 +	return 
  44.178 +		(mNormalID == rhs.mNormalID) && (mNormalOffsetX == rhs.mNormalOffsetX) && (mNormalOffsetY == rhs.mNormalOffsetY) &&
  44.179 +		(mNormalRepeatX == rhs.mNormalRepeatX) && (mNormalRepeatY == rhs.mNormalRepeatY) && (mNormalRotation == rhs.mNormalRotation) &&
  44.180 +		(mSpecularID == rhs.mSpecularID) && (mSpecularOffsetX == rhs.mSpecularOffsetX) && (mSpecularOffsetY == rhs.mSpecularOffsetY) &&
  44.181 +		(mSpecularRepeatX == rhs.mSpecularRepeatX) && (mSpecularRepeatY == rhs.mSpecularRepeatY) && (mSpecularRotation == rhs.mSpecularRotation) &&
  44.182 +		(mSpecularLightColor == rhs.mSpecularLightColor) && (mSpecularLightExponent == rhs.mSpecularLightExponent) &&
  44.183 +		(mEnvironmentIntensity == rhs.mEnvironmentIntensity) && (mDiffuseAlphaMode == rhs.mDiffuseAlphaMode) && (mAlphaMaskCutoff == rhs.mAlphaMaskCutoff);
  44.184 +}
  44.185 +
  44.186 +bool LLMaterial::operator != (const LLMaterial& rhs) const
  44.187 +{
  44.188 +	return !(*this == rhs);
  44.189 +}
  44.190 +
  44.191 +
  44.192 +U32 LLMaterial::getShaderMask(U32 alpha_mode)
  44.193 +{ //NEVER incorporate this value into the message system -- this function will vary depending on viewer implementation
  44.194 +	U32 ret = 0;
  44.195 +
  44.196 +	//two least significant bits are "diffuse alpha mode"
  44.197 +	if (alpha_mode != DIFFUSE_ALPHA_MODE_DEFAULT)
  44.198 +	{
  44.199 +		ret = alpha_mode;
  44.200 +	}
  44.201 +	else
  44.202 +	{
  44.203 +		ret = getDiffuseAlphaMode();
  44.204 +	}
  44.205 +
  44.206 +	llassert(ret < SHADER_COUNT);
  44.207 +
  44.208 +	//next bit is whether or not specular map is present
  44.209 +	const U32 SPEC_BIT = 0x4;
  44.210 +
  44.211 +	if (getSpecularID().notNull())
  44.212 +	{
  44.213 +		ret |= SPEC_BIT;
  44.214 +	}
  44.215 +
  44.216 +	llassert(ret < SHADER_COUNT);
  44.217 +	
  44.218 +	//next bit is whether or not normal map is present
  44.219 +	const U32 NORM_BIT = 0x8;
  44.220 +	if (getNormalID().notNull())
  44.221 +	{
  44.222 +		ret |= NORM_BIT;
  44.223 +	}
  44.224 +
  44.225 +	llassert(ret < SHADER_COUNT);
  44.226 +
  44.227 +	return ret;
  44.228 +}
  44.229 +
  44.230 +
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/indra/llprimitive/llmaterial.h	Thu Jul 18 18:43:58 2013 -0400
    45.3 @@ -0,0 +1,155 @@
    45.4 +/**
    45.5 + * @file llmaterial.h
    45.6 + * @brief Material definition
    45.7 + *
    45.8 + * $LicenseInfo:firstyear=2006&license=viewerlgpl$
    45.9 + * Second Life Viewer Source Code
   45.10 + * Copyright (C) 2010, Linden Research, Inc.
   45.11 + * 
   45.12 + * This library is free software; you can redistribute it and/or
   45.13 + * modify it under the terms of the GNU Lesser General Public
   45.14 + * License as published by the Free Software Foundation;
   45.15 + * version 2.1 of the License only.
   45.16 + * 
   45.17 + * This library is distributed in the hope that it will be useful,
   45.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   45.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   45.20 + * Lesser General Public License for more details.
   45.21 + * 
   45.22 + * You should have received a copy of the GNU Lesser General Public
   45.23 + * License along with this library; if not, write to the Free Software
   45.24 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   45.25 + * 
   45.26 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
   45.27 + * $/LicenseInfo$
   45.28 + */
   45.29 +
   45.30 +#ifndef LL_LLMATERIAL_H
   45.31 +#define LL_LLMATERIAL_H
   45.32 +
   45.33 +#include <boost/shared_ptr.hpp>
   45.34 +
   45.35 +#include "llmaterialid.h"
   45.36 +#include "llsd.h"
   45.37 +#include "v4coloru.h"
   45.38 +#include "llpointer.h"
   45.39 +#include "llrefcount.h"
   45.40 +
   45.41 +class LLMaterial : public LLRefCount
   45.42 +{
   45.43 +public:
   45.44 +
   45.45 +	typedef enum
   45.46 +	{
   45.47 +		DIFFUSE_ALPHA_MODE_NONE = 0,
   45.48 +		DIFFUSE_ALPHA_MODE_BLEND = 1,
   45.49 +		DIFFUSE_ALPHA_MODE_MASK = 2,
   45.50 +		DIFFUSE_ALPHA_MODE_EMISSIVE = 3,
   45.51 +		DIFFUSE_ALPHA_MODE_DEFAULT = 4,
   45.52 +	} eDiffuseAlphaMode;
   45.53 +
   45.54 +	typedef enum
   45.55 +	{
   45.56 +		SHADER_COUNT = 16,
   45.57 +		ALPHA_SHADER_COUNT = 4
   45.58 +	} eShaderCount;
   45.59 +
   45.60 +	
   45.61 +	
   45.62 +	static const U8			DEFAULT_SPECULAR_LIGHT_EXPONENT = ((U8)(0.2f * 255));
   45.63 +	static const LLColor4U	DEFAULT_SPECULAR_LIGHT_COLOR;
   45.64 +	static const U8			DEFAULT_ENV_INTENSITY = 0;
   45.65 +
   45.66 +	LLMaterial();
   45.67 +	LLMaterial(const LLSD& material_data);
   45.68 +
   45.69 +	LLSD asLLSD() const;
   45.70 +	void fromLLSD(const LLSD& material_data);
   45.71 +
   45.72 +	const LLUUID& getNormalID() const { return mNormalID; }
   45.73 +	void		setNormalID(const LLUUID& normal_id) { mNormalID = normal_id; }
   45.74 +	void		getNormalOffset(F32& offset_x, F32& offset_y) const { offset_x = mNormalOffsetX; offset_y = mNormalOffsetY; }
   45.75 +	F32		getNormalOffsetX() const { return mNormalOffsetX; }
   45.76 +	F32		getNormalOffsetY() const { return mNormalOffsetY; }
   45.77 +
   45.78 +	void		setNormalOffset(F32 offset_x, F32 offset_y) { mNormalOffsetX = offset_x; mNormalOffsetY = offset_y; }
   45.79 +	void		setNormalOffsetX(F32 offset_x) { mNormalOffsetX = offset_x; }
   45.80 +	void		setNormalOffsetY(F32 offset_y) { mNormalOffsetY = offset_y; }
   45.81 +
   45.82 +	void		getNormalRepeat(F32& repeat_x, F32& repeat_y) const { repeat_x = mNormalRepeatX; repeat_y = mNormalRepeatY; }
   45.83 +	F32		getNormalRepeatX() const { return mNormalRepeatX; }
   45.84 +	F32		getNormalRepeatY() const { return mNormalRepeatY; }
   45.85 +
   45.86 +	void		setNormalRepeat(F32 repeat_x, F32 repeat_y) { mNormalRepeatX = repeat_x; mNormalRepeatY = repeat_y; }
   45.87 +	void		setNormalRepeatX(F32 repeat_x) { mNormalRepeatX = repeat_x; }
   45.88 +	void		setNormalRepeatY(F32 repeat_y) { mNormalRepeatY = repeat_y; }
   45.89 +
   45.90 +	F32		getNormalRotation() const { return mNormalRotation; }
   45.91 +	void		setNormalRotation(F32 rot) { mNormalRotation = rot; }
   45.92 +
   45.93 +	const LLUUID& getSpecularID() const { return mSpecularID; }
   45.94 +	void		setSpecularID(const LLUUID& specular_id)  { mSpecularID = specular_id; }
   45.95 +	void		getSpecularOffset(F32& offset_x, F32& offset_y) const { offset_x = mSpecularOffsetX; offset_y = mSpecularOffsetY; }
   45.96 +	F32		getSpecularOffsetX() const { return mSpecularOffsetX; }
   45.97 +	F32		getSpecularOffsetY() const { return mSpecularOffsetY; }
   45.98 +
   45.99 +	void		setSpecularOffset(F32 offset_x, F32 offset_y) { mSpecularOffsetX = offset_x; mSpecularOffsetY = offset_y; }
  45.100 +	void		setSpecularOffsetX(F32 offset_x) { mSpecularOffsetX = offset_x; }
  45.101 +	void		setSpecularOffsetY(F32 offset_y) { mSpecularOffsetY = offset_y; }
  45.102 +
  45.103 +	void		getSpecularRepeat(F32& repeat_x, F32& repeat_y) const { repeat_x = mSpecularRepeatX; repeat_y = mSpecularRepeatY; }
  45.104 +	F32		getSpecularRepeatX() const { return mSpecularRepeatX; }
  45.105 +	F32		getSpecularRepeatY() const { return mSpecularRepeatY; }
  45.106 +
  45.107 +	void		setSpecularRepeat(F32 repeat_x, F32 repeat_y) { mSpecularRepeatX = repeat_x; mSpecularRepeatY = repeat_y; }
  45.108 +	void		setSpecularRepeatX(F32 repeat_x) { mSpecularRepeatX = repeat_x; }
  45.109 +	void		setSpecularRepeatY(F32 repeat_y) { mSpecularRepeatY = repeat_y; }
  45.110 +
  45.111 +	F32		getSpecularRotation() const { return mSpecularRotation; }
  45.112 +	void		setSpecularRotation(F32 rot) { mSpecularRotation = rot; }
  45.113 +
  45.114 +	const LLColor4U getSpecularLightColor() const { return mSpecularLightColor; }
  45.115 +	void		setSpecularLightColor(const LLColor4U& color) { mSpecularLightColor = color; }
  45.116 +	U8			getSpecularLightExponent() const { return mSpecularLightExponent; }
  45.117 +	void		setSpecularLightExponent(U8 exponent) { mSpecularLightExponent = exponent; }
  45.118 +	U8			getEnvironmentIntensity() const { return mEnvironmentIntensity; }
  45.119 +	void		setEnvironmentIntensity(U8 intensity) { mEnvironmentIntensity = intensity; }
  45.120 +	U8			getDiffuseAlphaMode() const { return mDiffuseAlphaMode; }
  45.121 +	void		setDiffuseAlphaMode(U8 alpha_mode) { mDiffuseAlphaMode = alpha_mode; }
  45.122 +	U8			getAlphaMaskCutoff() const { return mAlphaMaskCutoff; }
  45.123 +	void		setAlphaMaskCutoff(U8 cutoff) { mAlphaMaskCutoff = cutoff; }
  45.124 +
  45.125 +	bool		isNull() const;
  45.126 +	static const LLMaterial null;
  45.127 +
  45.128 +	bool		operator == (const LLMaterial& rhs) const;
  45.129 +	bool		operator != (const LLMaterial& rhs) const;
  45.130 +
  45.131 +	U32			getShaderMask(U32 alpha_mode = DIFFUSE_ALPHA_MODE_DEFAULT);
  45.132 +
  45.133 +protected:
  45.134 +	LLUUID		mNormalID;
  45.135 +	F32			mNormalOffsetX;
  45.136 +	F32			mNormalOffsetY;
  45.137 +	F32			mNormalRepeatX;
  45.138 +	F32			mNormalRepeatY;
  45.139 +	F32			mNormalRotation;
  45.140 +
  45.141 +	LLUUID		mSpecularID;
  45.142 +	F32			mSpecularOffsetX;
  45.143 +	F32			mSpecularOffsetY;
  45.144 +	F32			mSpecularRepeatX;
  45.145 +	F32			mSpecularRepeatY;
  45.146 +	F32			mSpecularRotation;
  45.147 +
  45.148 +	LLColor4U	mSpecularLightColor;
  45.149 +	U8			mSpecularLightExponent;
  45.150 +	U8			mEnvironmentIntensity;
  45.151 +	U8			mDiffuseAlphaMode;
  45.152 +	U8			mAlphaMaskCutoff;
  45.153 +};
  45.154 +
  45.155 +typedef LLPointer<LLMaterial> LLMaterialPtr;
  45.156 +
  45.157 +#endif // LL_LLMATERIAL_H
  45.158 +
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/indra/llprimitive/llmaterialid.cpp	Thu Jul 18 18:43:58 2013 -0400
    46.3 @@ -0,0 +1,183 @@
    46.4 +/** 
    46.5 +* @file llmaterialid.cpp
    46.6 +* @brief Implementation of llmaterialid
    46.7 +* @author Stinson@lindenlab.com
    46.8 +*
    46.9 +* $LicenseInfo:firstyear=2012&license=viewerlgpl$
   46.10 +* Second Life Viewer Source Code
   46.11 +* Copyright (C) 2012, Linden Research, Inc.
   46.12 +*
   46.13 +* This library is free software; you can redistribute it and/or
   46.14 +* modify it under the terms of the GNU Lesser General Public
   46.15 +* License as published by the Free Software Foundation;
   46.16 +* version 2.1 of the License only.
   46.17 +*
   46.18 +* This library is distributed in the hope that it will be useful,
   46.19 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
   46.20 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   46.21 +* Lesser General Public License for more details.
   46.22 +*
   46.23 +* You should have received a copy of the GNU Lesser General Public
   46.24 +* License along with this library; if not, write to the Free Software
   46.25 +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   46.26 +*
   46.27 +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
   46.28 +* $/LicenseInfo$
   46.29 +*/
   46.30 +
   46.31 +#include "linden_common.h"
   46.32 +
   46.33 +#include "llmaterialid.h"
   46.34 +
   46.35 +#include <string>
   46.36 +
   46.37 +#include "llformat.h"
   46.38 +
   46.39 +const LLMaterialID LLMaterialID::null;
   46.40 +
   46.41 +LLMaterialID::LLMaterialID()
   46.42 +{
   46.43 +	clear();
   46.44 +}
   46.45 +
   46.46 +LLMaterialID::LLMaterialID(const LLSD& pMaterialID)
   46.47 +{
   46.48 +	llassert(pMaterialID.isBinary());
   46.49 +	parseFromBinary(pMaterialID.asBinary());
   46.50 +}
   46.51 +
   46.52 +LLMaterialID::LLMaterialID(const LLSD::Binary& pMaterialID)
   46.53 +{
   46.54 +	parseFromBinary(pMaterialID);
   46.55 +}
   46.56 +
   46.57 +LLMaterialID::LLMaterialID(const void* pMemory)
   46.58 +{
   46.59 +	set(pMemory);
   46.60 +}
   46.61 +
   46.62 +LLMaterialID::LLMaterialID(const LLMaterialID& pOtherMaterialID)
   46.63 +{
   46.64 +	copyFromOtherMaterialID(pOtherMaterialID);
   46.65 +}
   46.66 +
   46.67 +LLMaterialID::~LLMaterialID()
   46.68 +{
   46.69 +}
   46.70 +
   46.71 +bool LLMaterialID::operator == (const LLMaterialID& pOtherMaterialID) const
   46.72 +{
   46.73 +	return (compareToOtherMaterialID(pOtherMaterialID) == 0);
   46.74 +}
   46.75 +
   46.76 +bool LLMaterialID::operator != (const LLMaterialID& pOtherMaterialID) const
   46.77 +{
   46.78 +	return (compareToOtherMaterialID(pOtherMaterialID) != 0);
   46.79 +}
   46.80 +
   46.81 +bool LLMaterialID::operator < (const LLMaterialID& pOtherMaterialID) const
   46.82 +{
   46.83 +	return (compareToOtherMaterialID(pOtherMaterialID) < 0);
   46.84 +}
   46.85 +
   46.86 +bool LLMaterialID::operator <= (const LLMaterialID& pOtherMaterialID) const
   46.87 +{
   46.88 +	return (compareToOtherMaterialID(pOtherMaterialID) <= 0);
   46.89 +}
   46.90 +
   46.91 +bool LLMaterialID::operator > (const LLMaterialID& pOtherMaterialID) const
   46.92 +{
   46.93 +	return (compareToOtherMaterialID(pOtherMaterialID) > 0);
   46.94 +}
   46.95 +
   46.96 +bool LLMaterialID::operator >= (const LLMaterialID& pOtherMaterialID) const
   46.97 +{
   46.98 +	return (compareToOtherMaterialID(pOtherMaterialID) >= 0);
   46.99 +}
  46.100 +
  46.101 +LLMaterialID& LLMaterialID::operator = (const LLMaterialID& pOtherMaterialID)
  46.102 +{
  46.103 +	copyFromOtherMaterialID(pOtherMaterialID);
  46.104 +	return (*this);
  46.105 +}
  46.106 +
  46.107 +bool LLMaterialID::isNull() const
  46.108 +{
  46.109 +	return (compareToOtherMaterialID(LLMaterialID::null) == 0);
  46.110 +}
  46.111 +
  46.112 +const U8* LLMaterialID::get() const
  46.113 +{
  46.114 +	return mID;
  46.115 +}
  46.116 +
  46.117 +void LLMaterialID::set(const void* pMemory)
  46.118 +{
  46.119 +	llassert(pMemory != NULL);
  46.120 +
  46.121 +	// assumes that the required size of memory is available
  46.122 +	memcpy(mID, pMemory, MATERIAL_ID_SIZE * sizeof(U8));
  46.123 +}
  46.124 +
  46.125 +void LLMaterialID::clear()
  46.126 +{
  46.127 +	memset(mID, 0, MATERIAL_ID_SIZE * sizeof(U8));
  46.128 +}
  46.129 +
  46.130 +LLSD LLMaterialID::asLLSD() const
  46.131 +{
  46.132 +	LLSD::Binary materialIDBinary;
  46.133 +
  46.134 +	materialIDBinary.resize(MATERIAL_ID_SIZE * sizeof(U8));
  46.135 +	memcpy(materialIDBinary.data(), mID, MATERIAL_ID_SIZE * sizeof(U8));
  46.136 +
  46.137 +	LLSD materialID = materialIDBinary;
  46.138 +	return materialID;
  46.139 +}
  46.140 +
  46.141 +std::string LLMaterialID::asString() const
  46.142 +{
  46.143 +	std::string materialIDString;
  46.144 +	for (unsigned int i = 0U; i < static_cast<unsigned int>(MATERIAL_ID_SIZE / sizeof(U32)); ++i)
  46.145 +	{
  46.146 +		if (i != 0U)
  46.147 +		{
  46.148 +			materialIDString += "-";
  46.149 +		}
  46.150 +		const U32 *value = reinterpret_cast<const U32*>(&get()[i * sizeof(U32)]);
  46.151 +		materialIDString += llformat("%08x", *value);
  46.152 +	}
  46.153 +	return materialIDString;
  46.154 +}
  46.155 +
  46.156 +std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id)
  46.157 +{
  46.158 +	s << material_id.asString();
  46.159 +	return s;
  46.160 +}
  46.161 +
  46.162 +
  46.163 +void LLMaterialID::parseFromBinary (const LLSD::Binary& pMaterialID)
  46.164 +{
  46.165 +	llassert(pMaterialID.size() == (MATERIAL_ID_SIZE * sizeof(U8)));
  46.166 +	memcpy(mID, &pMaterialID[0], MATERIAL_ID_SIZE * sizeof(U8));
  46.167 +}
  46.168 +
  46.169 +void LLMaterialID::copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID)
  46.170 +{
  46.171 +	memcpy(mID, pOtherMaterialID.get(), MATERIAL_ID_SIZE * sizeof(U8));
  46.172 +}
  46.173 +
  46.174 +int LLMaterialID::compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const
  46.175 +{
  46.176 +	int retVal = 0;
  46.177 +
  46.178 +	for (unsigned int i = 0U; (retVal == 0) && (i < static_cast<unsigned int>(MATERIAL_ID_SIZE / sizeof(U32))); ++i)
  46.179 +	{
  46.180 +		const U32 *thisValue = reinterpret_cast<const U32*>(&get()[i * sizeof(U32)]);
  46.181 +		const U32 *otherValue = reinterpret_cast<const U32*>(&pOtherMaterialID.get()[i * sizeof(U32)]);
  46.182 +		retVal = ((*thisValue < *otherValue) ? -1 : ((*thisValue > *otherValue) ? 1 : 0));
  46.183 +	}
  46.184 +
  46.185 +	return retVal;
  46.186 +}
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/indra/llprimitive/llmaterialid.h	Thu Jul 18 18:43:58 2013 -0400
    47.3 @@ -0,0 +1,76 @@
    47.4 +/** 
    47.5 +* @file   llmaterialid.h
    47.6 +* @brief  Header file for llmaterialid
    47.7 +* @author Stinson@lindenlab.com
    47.8 +*
    47.9 +* $LicenseInfo:firstyear=2012&license=viewerlgpl$
   47.10 +* Second Life Viewer Source Code
   47.11 +* Copyright (C) 2012, Linden Research, Inc.
   47.12 +*
   47.13 +* This library is free software; you can redistribute it and/or
   47.14 +* modify it under the terms of the GNU Lesser General Public
   47.15 +* License as published by the Free Software Foundation;
   47.16 +* version 2.1 of the License only.
   47.17 +*
   47.18 +* This library is distributed in the hope that it will be useful,
   47.19 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
   47.20 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   47.21 +* Lesser General Public License for more details.
   47.22 +*
   47.23 +* You should have received a copy of the GNU Lesser General Public
   47.24 +* License along with this library; if not, write to the Free Software
   47.25 +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   47.26 +*
   47.27 +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
   47.28 +* $/LicenseInfo$
   47.29 +*/
   47.30 +#ifndef LL_LLMATERIALID_H
   47.31 +#define LL_LLMATERIALID_H
   47.32 +
   47.33 +#define MATERIAL_ID_SIZE 16
   47.34 +
   47.35 +#include <string>
   47.36 +
   47.37 +class LLMaterialID
   47.38 +{
   47.39 +public:
   47.40 +	LLMaterialID();
   47.41 +	LLMaterialID(const LLSD& pMaterialID);
   47.42 +	LLMaterialID(const LLSD::Binary& pMaterialID);
   47.43 +	LLMaterialID(const void* pMemory);
   47.44 +	LLMaterialID(const LLMaterialID& pOtherMaterialID);
   47.45 +	~LLMaterialID();
   47.46 +
   47.47 +	bool          operator == (const LLMaterialID& pOtherMaterialID) const;
   47.48 +	bool          operator != (const LLMaterialID& pOtherMaterialID) const;
   47.49 +
   47.50 +	bool          operator < (const LLMaterialID& pOtherMaterialID) const;
   47.51 +	bool          operator <= (const LLMaterialID& pOtherMaterialID) const;
   47.52 +	bool          operator > (const LLMaterialID& pOtherMaterialID) const;
   47.53 +	bool          operator >= (const LLMaterialID& pOtherMaterialID) const;
   47.54 +
   47.55 +	LLMaterialID& operator = (const LLMaterialID& pOtherMaterialID);
   47.56 +
   47.57 +	bool          isNull() const;
   47.58 +
   47.59 +	const U8*     get() const;
   47.60 +	void          set(const void* pMemory);
   47.61 +	void          clear();
   47.62 +
   47.63 +	LLSD          asLLSD() const;
   47.64 +	std::string   asString() const;
   47.65 +
   47.66 +	friend std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id);
   47.67 +
   47.68 +	static const LLMaterialID null;
   47.69 +
   47.70 +private:
   47.71 +	void parseFromBinary(const LLSD::Binary& pMaterialID);
   47.72 +	void copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID);
   47.73 +	int  compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const;
   47.74 +
   47.75 +	U8 mID[MATERIAL_ID_SIZE];
   47.76 +} ;
   47.77 +
   47.78 +#endif // LL_LLMATERIALID_H
   47.79 +
    48.1 --- a/indra/llprimitive/llprimitive.cpp	Thu Jul 18 15:14:55 2013 -0400
    48.2 +++ b/indra/llprimitive/llprimitive.cpp	Thu Jul 18 18:43:58 2013 -0400
    48.3 @@ -39,6 +39,7 @@
    48.4  #include "llsdutil_math.h"
    48.5  #include "llprimtexturelist.h"
    48.6  #include "imageids.h"
    48.7 +#include "llmaterialid.h"
    48.8  
    48.9  /**
   48.10   * exported constants
   48.11 @@ -314,6 +315,15 @@
   48.12  	return mTextureList.setRotation(index, r);
   48.13  }
   48.14  
   48.15 +S32 LLPrimitive::setTEMaterialID(const U8 index, const LLMaterialID& pMaterialID)
   48.16 +{
   48.17 +	return mTextureList.setMaterialID(index, pMaterialID);
   48.18 +}
   48.19 +
   48.20 +S32 LLPrimitive::setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams)
   48.21 +{
   48.22 +	return mTextureList.setMaterialParams(index, pMaterialParams);
   48.23 +}
   48.24  
   48.25  //===============================================================
   48.26  S32  LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump)
   48.27 @@ -364,6 +374,23 @@
   48.28  	return mTextureList.setGlow(index, glow);
   48.29  }
   48.30  
   48.31 +void LLPrimitive::setAllTESelected(bool sel)
   48.32 +{
   48.33 +	for (int i = 0, cnt = getNumTEs(); i < cnt; i++)
   48.34 +	{
   48.35 +		setTESelected(i, sel);
   48.36 +	}
   48.37 +}
   48.38 +	
   48.39 +void LLPrimitive::setTESelected(const U8 te, bool sel)
   48.40 +{
   48.41 +	LLTextureEntry* tep = getTE(te);
   48.42 +	if ( (tep) && (tep->setSelected(sel)) && (!sel) && (tep->hasPendingMaterialUpdate()) )
   48.43 +	{
   48.44 +		LLMaterialID material_id = tep->getMaterialID();
   48.45 +		setTEMaterialID(te, material_id);
   48.46 +	}
   48.47 +}
   48.48  
   48.49  LLPCode LLPrimitive::legacyToPCode(const U8 legacy)
   48.50  {
   48.51 @@ -1044,7 +1071,7 @@
   48.52  	
   48.53  	while ((cur_ptr < buffer_end) && (*cur_ptr != 0))
   48.54  	{
   48.55 -//		llinfos << "TE exception" << llendl;
   48.56 +		LL_DEBUGS("TEFieldDecode") << "TE exception" << LL_ENDL;
   48.57  		i = 0;
   48.58  		while (*cur_ptr & 0x80)
   48.59  		{
   48.60 @@ -1059,14 +1086,16 @@
   48.61  			if (i & 0x01)
   48.62  			{
   48.63  				htonmemcpy(data_ptr+(j*data_size),cur_ptr,type,data_size);
   48.64 -//				char foo[64];
   48.65 -//				sprintf(foo,"%x %x",*(data_ptr+(j*data_size)), *(data_ptr+(j*data_size)+1));
   48.66 -//				llinfos << "Assigning " << foo << " to face " << j << llendl;			
   48.67 +				LL_DEBUGS("TEFieldDecode") << "Assigning " ;
   48.68 +				char foo[64];
   48.69 +				sprintf(foo,"%x %x",*(data_ptr+(j*data_size)), *(data_ptr+(j*data_size)+1));
   48.70 +				LL_CONT << foo << " to face " << j << LL_ENDL;
   48.71  			}
   48.72  			i = i >> 1;
   48.73  		}
   48.74  		cur_ptr += data_size;		
   48.75  	}
   48.76 +	llassert(cur_ptr <= buffer_end); // buffer underrun
   48.77  	return (S32)(cur_ptr - start_loc);
   48.78  }
   48.79  
   48.80 @@ -1088,6 +1117,7 @@
   48.81  	U8	   bump[MAX_TES];
   48.82  	U8	   media_flags[MAX_TES];
   48.83      U8     glow[MAX_TES];
   48.84 +	U8     material_data[MAX_TES*16];
   48.85  	
   48.86  	const U32 MAX_TE_BUFFER = 4096;
   48.87  	U8 packed_buffer[MAX_TE_BUFFER];
   48.88 @@ -1125,6 +1155,9 @@
   48.89  			bump[face_index] = te->getBumpShinyFullbright();
   48.90  			media_flags[face_index] = te->getMediaTexGen();
   48.91  			glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
   48.92 +
   48.93 +			// Directly sending material_ids is not safe!
   48.94 +			memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16);	/* Flawfinder: ignore */ 
   48.95  		}
   48.96  
   48.97  		cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
   48.98 @@ -1146,6 +1179,8 @@
   48.99  		cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
  48.100  		*cur_ptr++ = 0;
  48.101  		cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
  48.102 +		*cur_ptr++ = 0;
  48.103 +		cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID);
  48.104  	}
  48.105     	mesgsys->addBinaryDataFast(_PREHASH_TextureEntry, packed_buffer, (S32)(cur_ptr - packed_buffer));
  48.106  
  48.107 @@ -1167,6 +1202,7 @@
  48.108  	U8	   bump[MAX_TES];
  48.109  	U8	   media_flags[MAX_TES];
  48.110      U8     glow[MAX_TES];
  48.111 +	U8     material_data[MAX_TES*16];
  48.112  	
  48.113  	const U32 MAX_TE_BUFFER = 4096;
  48.114  	U8 packed_buffer[MAX_TE_BUFFER];
  48.115 @@ -1204,6 +1240,9 @@
  48.116  			bump[face_index] = te->getBumpShinyFullbright();
  48.117  			media_flags[face_index] = te->getMediaTexGen();
  48.118              glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
  48.119 +
  48.120 +			// Directly sending material_ids is not safe!
  48.121 +			memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16);	/* Flawfinder: ignore */ 
  48.122  		}
  48.123  
  48.124  		cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
  48.125 @@ -1225,6 +1264,8 @@
  48.126  		cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
  48.127  		*cur_ptr++ = 0;
  48.128  		cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
  48.129 +		*cur_ptr++ = 0;
  48.130 +		cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID);
  48.131  	}
  48.132  
  48.133  	dp.packBinaryData(packed_buffer, (S32)(cur_ptr - packed_buffer), "TextureEntry");
  48.134 @@ -1234,6 +1275,9 @@
  48.135  S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec)
  48.136  {
  48.137  	S32 retval = 0;
  48.138 +   // temp buffer for material ID processing
  48.139 +   // data will end up in tec.material_id[]	
  48.140 +   U8 material_data[LLTEContents::MAX_TES*16];
  48.141  
  48.142  	if (block_num < 0)
  48.143  	{
  48.144 @@ -1282,14 +1326,29 @@
  48.145  	cur_ptr++;
  48.146  	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.glow, 1, tec.face_count, MVT_U8);
  48.147  
  48.148 +	if (cur_ptr < tec.packed_buffer + tec.size)
  48.149 +	{
  48.150 +		cur_ptr++;
  48.151 +		cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)material_data, 16, tec.face_count, MVT_LLUUID);
  48.152 +	}
  48.153 +	else
  48.154 +	{
  48.155 +		memset(material_data, 0, sizeof(material_data));
  48.156 +	}
  48.157 +	
  48.158 +	for (U32 i = 0; i < tec.face_count; i++)
  48.159 +	{
  48.160 +		tec.material_ids[i].set(&material_data[i * 16]);
  48.161 +	}
  48.162 +	
  48.163  	retval = 1;
  48.164  	return retval;
  48.165 -}
  48.166 -
  48.167 +	}
  48.168 +	
  48.169  S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec)
  48.170  {
  48.171  	S32 retval = 0;
  48.172 -
  48.173 +	
  48.174  	LLColor4 color;
  48.175  	LLColor4U coloru;
  48.176  	for (U32 i = 0; i < tec.face_count; i++)
  48.177 @@ -1302,6 +1361,9 @@
  48.178  		retval |= setTEBumpShinyFullbright(i, tec.bump[i]);
  48.179  		retval |= setTEMediaTexGen(i, tec.media_flags[i]);
  48.180  		retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF);
  48.181 +		
  48.182 +                retval |= setTEMaterialID(i, tec.material_ids[i]);
  48.183 +		
  48.184  		coloru = LLColor4U(tec.colors + 4*i);
  48.185  
  48.186  		// Note:  This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
  48.187 @@ -1336,6 +1398,7 @@
  48.188  
  48.189  	// Avoid construction of 32 UUIDs per call
  48.190  	static LLUUID image_ids[MAX_TES];
  48.191 +	static LLMaterialID material_ids[MAX_TES];
  48.192  
  48.193  	U8     image_data[MAX_TES*16];
  48.194  	U8	   colors[MAX_TES*4];
  48.195 @@ -1347,6 +1410,7 @@
  48.196  	U8	   bump[MAX_TES];
  48.197  	U8	   media_flags[MAX_TES];
  48.198      U8     glow[MAX_TES];
  48.199 +	U8     material_data[MAX_TES*16];
  48.200  
  48.201  	const U32 MAX_TE_BUFFER = 4096;
  48.202  	U8 packed_buffer[MAX_TE_BUFFER];
  48.203 @@ -1389,10 +1453,20 @@
  48.204  	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8);
  48.205  	cur_ptr++;
  48.206  	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8);
  48.207 +	if (cur_ptr < packed_buffer + size)
  48.208 +	{
  48.209 +		cur_ptr++;
  48.210 +		cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)material_data, 16, face_count, MVT_LLUUID);
  48.211 +	}
  48.212 +	else
  48.213 +	{
  48.214 +		memset(material_data, 0, sizeof(material_data));
  48.215 +	}
  48.216  
  48.217  	for (i = 0; i < face_count; i++)
  48.218  	{
  48.219  		memcpy(image_ids[i].mData,&image_data[i*16],16);	/* Flawfinder: ignore */ 	
  48.220 +		material_ids[i].set(&material_data[i * 16]);
  48.221  	}
  48.222  	
  48.223  	LLColor4 color;
  48.224 @@ -1406,6 +1480,7 @@
  48.225  		retval |= setTEBumpShinyFullbright(i, bump[i]);
  48.226  		retval |= setTEMediaTexGen(i, media_flags[i]);
  48.227  		retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF);
  48.228 +		retval |= setTEMaterialID(i, material_ids[i]);
  48.229  		coloru = LLColor4U(colors + 4*i);
  48.230  
  48.231  		// Note:  This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
    49.1 --- a/indra/llprimitive/llprimitive.h	Thu Jul 18 15:14:55 2013 -0400
    49.2 +++ b/indra/llprimitive/llprimitive.h	Thu Jul 18 18:43:58 2013 -0400
    49.3 @@ -42,6 +42,7 @@
    49.4  class LLVolumeParams;
    49.5  class LLColor4;
    49.6  class LLColor3;
    49.7 +class LLMaterialID;
    49.8  class LLTextureEntry;
    49.9  class LLDataPacker;
   49.10  class LLVolumeMgr;
   49.11 @@ -309,7 +310,8 @@
   49.12  	U8	   bump[MAX_TES];
   49.13  	U8	   media_flags[MAX_TES];
   49.14      U8     glow[MAX_TES];
   49.15 -	
   49.16 +	LLMaterialID material_ids[MAX_TES];
   49.17 +
   49.18  	static const U32 MAX_TE_BUFFER = 4096;
   49.19  	U8 packed_buffer[MAX_TE_BUFFER];
   49.20  
   49.21 @@ -359,6 +361,7 @@
   49.22  	LLTextureEntry* getTE(const U8 te_num) const;
   49.23  
   49.24  	virtual void setNumTEs(const U8 num_tes);
   49.25 +	virtual void setAllTESelected(bool sel);
   49.26  	virtual void setAllTETextures(const LLUUID &tex_id);
   49.27  	virtual void setTE(const U8 index, const LLTextureEntry& te);
   49.28  	virtual S32 setTEColor(const U8 te, const LLColor4 &color);
   49.29 @@ -381,7 +384,10 @@
   49.30  	virtual S32 setTEFullbright(const U8 te, const U8 fullbright);
   49.31  	virtual S32 setTEMediaFlags(const U8 te, const U8 flags);
   49.32  	virtual S32 setTEGlow(const U8 te, const F32 glow);
   49.33 +	virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
   49.34 +	virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);
   49.35  	virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed
   49.36 +	virtual void setTESelected(const U8 te, bool sel);
   49.37  
   49.38  	void copyTEs(const LLPrimitive *primitive);
   49.39  	S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const;
    50.1 --- a/indra/llprimitive/llprimtexturelist.cpp	Thu Jul 18 15:14:55 2013 -0400
    50.2 +++ b/indra/llprimitive/llprimtexturelist.cpp	Thu Jul 18 18:43:58 2013 -0400
    50.3 @@ -27,6 +27,7 @@
    50.4  #include "linden_common.h"
    50.5  
    50.6  #include "llprimtexturelist.h"
    50.7 +#include "llmaterialid.h"
    50.8  #include "lltextureentry.h"
    50.9  
   50.10  // static 
   50.11 @@ -358,6 +359,24 @@
   50.12  	return TEM_CHANGE_NONE;
   50.13  }
   50.14  
   50.15 +S32 LLPrimTextureList::setMaterialID(const U8 index, const LLMaterialID& pMaterialID)
   50.16 +{
   50.17 +	if (index < mEntryList.size())
   50.18 +	{
   50.19 +		return mEntryList[index]->setMaterialID(pMaterialID);
   50.20 +	}
   50.21 +	return TEM_CHANGE_NONE;
   50.22 +}
   50.23 +
   50.24 +S32 LLPrimTextureList::setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams)
   50.25 +{
   50.26 +	if (index < mEntryList.size())
   50.27 +	{
   50.28 +		return mEntryList[index]->setMaterialParams(pMaterialParams);
   50.29 +	}
   50.30 +	return TEM_CHANGE_NONE;
   50.31 +}
   50.32 +
   50.33  S32 LLPrimTextureList::size() const
   50.34  {
   50.35  	return mEntryList.size();
    51.1 --- a/indra/llprimitive/llprimtexturelist.h	Thu Jul 18 15:14:55 2013 -0400
    51.2 +++ b/indra/llprimitive/llprimtexturelist.h	Thu Jul 18 18:43:58 2013 -0400
    51.3 @@ -31,9 +31,11 @@
    51.4  #include "lluuid.h"
    51.5  #include "v3color.h"
    51.6  #include "v4color.h"
    51.7 +#include "llmaterial.h"
    51.8  
    51.9  
   51.10  class LLTextureEntry;
   51.11 +class LLMaterialID;
   51.12  
   51.13  // this is a list of LLTextureEntry*'s because in practice the list's elements
   51.14  // are of some derived class: LLFooTextureEntry
   51.15 @@ -102,6 +104,8 @@
   51.16  	S32 setFullbright(const U8 index, const U8 t);
   51.17  	S32 setMediaFlags(const U8 index, const U8 media_flags);
   51.18  	S32 setGlow(const U8 index, const F32 glow);
   51.19 +	S32 setMaterialID(const U8 index, const LLMaterialID& pMaterialID);
   51.20 +	S32 setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);
   51.21  
   51.22  	S32 size() const;
   51.23  
    52.1 --- a/indra/llprimitive/lltextureentry.cpp	Thu Jul 18 15:14:55 2013 -0400
    52.2 +++ b/indra/llprimitive/lltextureentry.cpp	Thu Jul 18 18:43:58 2013 -0400
    52.3 @@ -29,6 +29,7 @@
    52.4  #include "lluuid.h"
    52.5  #include "llmediaentry.h"
    52.6  #include "lltextureentry.h"
    52.7 +#include "llmaterialid.h"
    52.8  #include "llsdutil_math.h"
    52.9  #include "v4color.h"
   52.10  
   52.11 @@ -60,18 +61,24 @@
   52.12  //===============================================================
   52.13  LLTextureEntry::LLTextureEntry()
   52.14    : mMediaEntry(NULL)
   52.15 +  , mSelected(false)
   52.16 +  , mMaterialUpdatePending(false)
   52.17  {
   52.18  	init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
   52.19  }
   52.20  
   52.21  LLTextureEntry::LLTextureEntry(const LLUUID& tex_id)
   52.22    : mMediaEntry(NULL)
   52.23 +  , mSelected(false)
   52.24 +  , mMaterialUpdatePending(false)
   52.25  {
   52.26  	init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
   52.27  }
   52.28  
   52.29  LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
   52.30    : mMediaEntry(NULL)
   52.31 +  , mSelected(false)
   52.32 +  , mMaterialUpdatePending(false)
   52.33  {
   52.34  	mID = rhs.mID;
   52.35  	mScaleS = rhs.mScaleS;
   52.36 @@ -83,6 +90,8 @@
   52.37  	mBump = rhs.mBump;
   52.38  	mMediaFlags = rhs.mMediaFlags;
   52.39  	mGlow = rhs.mGlow;
   52.40 +	mMaterialID = rhs.mMaterialID;
   52.41 +	mMaterial = rhs.mMaterial;
   52.42  	if (rhs.mMediaEntry != NULL) {
   52.43  		// Make a copy
   52.44  		mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
   52.45 @@ -103,6 +112,8 @@
   52.46  		mBump = rhs.mBump;
   52.47  		mMediaFlags = rhs.mMediaFlags;
   52.48  		mGlow = rhs.mGlow;
   52.49 +		mMaterialID = rhs.mMaterialID;
   52.50 +		mMaterial = rhs.mMaterial;
   52.51  		if (mMediaEntry != NULL) {
   52.52  			delete mMediaEntry;
   52.53  		}
   52.54 @@ -130,6 +141,7 @@
   52.55  	mBump = bump;
   52.56  	mMediaFlags = 0x0;
   52.57      mGlow = 0;
   52.58 +	mMaterialID.clear();
   52.59  	
   52.60  	setColor(LLColor4(1.f, 1.f, 1.f, 1.f));
   52.61  	if (mMediaEntry != NULL) {
   52.62 @@ -159,6 +171,7 @@
   52.63  	if (mBump != rhs.mBump) return (true);
   52.64  	if (mMediaFlags != rhs.mMediaFlags) return (true);
   52.65  	if (mGlow != rhs.mGlow) return (true);
   52.66 +	if (mMaterialID != rhs.mMaterialID) return (true);
   52.67  	return(false);
   52.68  }
   52.69  
   52.70 @@ -174,6 +187,7 @@
   52.71  	if (mBump != rhs.mBump) return (false);
   52.72  	if (mMediaFlags != rhs.mMediaFlags) return false;
   52.73  	if (mGlow != rhs.mGlow) return false;
   52.74 +	if (mMaterialID != rhs.mMaterialID) return (false);
   52.75  	return(true);
   52.76  }
   52.77  
   52.78 @@ -523,6 +537,34 @@
   52.79  	return TEM_CHANGE_NONE;
   52.80  }
   52.81  
   52.82 +S32 LLTextureEntry::setMaterialID(const LLMaterialID& pMaterialID)
   52.83 +{
   52.84 +	if ( (mMaterialID != pMaterialID) || (mMaterialUpdatePending && !mSelected) )
   52.85 +	{
   52.86 +		if (mSelected)
   52.87 +		{
   52.88 +			mMaterialUpdatePending = true;
   52.89 +			mMaterialID = pMaterialID;
   52.90 +			return TEM_CHANGE_NONE;
   52.91 +		}
   52.92 +
   52.93 +		mMaterialUpdatePending = false;
   52.94 +		mMaterialID = pMaterialID;
   52.95 +		return TEM_CHANGE_TEXTURE;
   52.96 +	}
   52.97 +	return TEM_CHANGE_NONE;
   52.98 +}
   52.99 +
  52.100 +S32 LLTextureEntry::setMaterialParams(const LLMaterialPtr pMaterialParams)
  52.101 +{
  52.102 +	if (mSelected)
  52.103 +	{
  52.104 +		mMaterialUpdatePending = true;
  52.105 +	}
  52.106 +	mMaterial = pMaterialParams;
  52.107 +	return TEM_CHANGE_TEXTURE;
  52.108 +}
  52.109 +
  52.110  void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry)
  52.111  {
  52.112      mMediaFlags |= MF_HAS_MEDIA;
    53.1 --- a/indra/llprimitive/lltextureentry.h	Thu Jul 18 15:14:55 2013 -0400
    53.2 +++ b/indra/llprimitive/lltextureentry.h	Thu Jul 18 18:43:58 2013 -0400
    53.3 @@ -30,6 +30,8 @@
    53.4  #include "lluuid.h"
    53.5  #include "v4color.h"
    53.6  #include "llsd.h"
    53.7 +#include "llmaterialid.h"
    53.8 +#include "llmaterial.h"
    53.9  
   53.10  // These bits are used while unpacking TEM messages to tell which aspects of
   53.11  // the texture entry changed.
   53.12 @@ -98,6 +100,10 @@
   53.13  
   53.14  	void init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 offset_s, F32 offset_t, F32 rotation, U8 bump);
   53.15  
   53.16 +	bool hasPendingMaterialUpdate() const { return mMaterialUpdatePending; }
   53.17 +	bool isSelected() const { return mSelected; }
   53.18 +	bool setSelected(bool sel) { bool prev_sel = mSelected; mSelected = sel; return prev_sel; }
   53.19 +
   53.20  	// These return a TEM_ flag from above to indicate if something changed.
   53.21  	S32  setID (const LLUUID &tex_id);
   53.22  	S32  setColor(const LLColor4 &color);
   53.23 @@ -121,11 +127,19 @@
   53.24  	S32	 setTexGen(U8 texGen);
   53.25  	S32  setMediaTexGen(U8 media);
   53.26      S32  setGlow(F32 glow);
   53.27 +	S32  setMaterialID(const LLMaterialID& pMaterialID);
   53.28 +	S32  setMaterialParams(const LLMaterialPtr pMaterialParams);
   53.29  	
   53.30  	virtual const LLUUID &getID() const { return mID; }
   53.31  	const LLColor4 &getColor() const { return mColor; }
   53.32  	void getScale(F32 *s, F32 *t) const { *s = mScaleS; *t = mScaleT; }
   53.33 +	F32  getScaleS() const { return mScaleS; }
   53.34 +	F32  getScaleT() const { return mScaleT; }
   53.35 +
   53.36  	void getOffset(F32 *s, F32 *t) const { *s = mOffsetS; *t = mOffsetT; }
   53.37 +	F32  getOffsetS() const { return mOffsetS; }
   53.38 +	F32  getOffsetT() const { return mOffsetT; }
   53.39 +
   53.40  	F32  getRotation() const { return mRotation; }
   53.41  	void getRotation(F32 *theta) const { *theta = mRotation; }
   53.42  
   53.43 @@ -136,9 +150,11 @@
   53.44   	U8	 getBumpShinyFullbright() const { return mBump; }
   53.45  
   53.46  	U8	 getMediaFlags() const { return mMediaFlags & TEM_MEDIA_MASK; }
   53.47 -	U8	 getTexGen() const	{ return mMediaFlags & TEM_TEX_GEN_MASK; }
   53.48 +	LLTextureEntry::e_texgen	 getTexGen() const	{ return LLTextureEntry::e_texgen(mMediaFlags & TEM_TEX_GEN_MASK); }
   53.49  	U8	 getMediaTexGen() const { return mMediaFlags; }
   53.50      F32  getGlow() const { return mGlow; }
   53.51 +	const LLMaterialID& getMaterialID() const { return mMaterialID; };
   53.52 +	const LLMaterialPtr getMaterialParams() const { return mMaterial; };
   53.53  
   53.54      // *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL.
   53.55      // CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData()
   53.56 @@ -188,11 +204,15 @@
   53.57  	static const char* TEXTURE_MEDIA_DATA_KEY;
   53.58  
   53.59  protected:
   53.60 +	bool                mSelected;
   53.61  	LLUUID				mID;					// Texture GUID
   53.62  	LLColor4			mColor;
   53.63  	U8					mBump;					// Bump map, shiny, and fullbright
   53.64  	U8					mMediaFlags;			// replace with web page, movie, etc.
   53.65  	F32                 mGlow;
   53.66 +	bool                mMaterialUpdatePending;
   53.67 +	LLMaterialID        mMaterialID;
   53.68 +	LLMaterialPtr		mMaterial;
   53.69  
   53.70  	// Note the media data is not sent via the same message structure as the rest of the TE
   53.71  	LLMediaEntry*		mMediaEntry;			// The media data for the face
    54.1 --- a/indra/llrender/CMakeLists.txt	Thu Jul 18 15:14:55 2013 -0400
    54.2 +++ b/indra/llrender/CMakeLists.txt	Thu Jul 18 18:43:58 2013 -0400
    54.3 @@ -92,7 +92,7 @@
    54.4  
    54.5    set_property(TARGET llrenderheadless
    54.6      PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1
    54.7 -    )
    54.8 +      )
    54.9  
   54.10    target_link_libraries(llrenderheadless
   54.11      ${LLCOMMON_LIBRARIES}
    55.1 --- a/indra/llrender/llgl.cpp	Thu Jul 18 15:14:55 2013 -0400
    55.2 +++ b/indra/llrender/llgl.cpp	Thu Jul 18 18:43:58 2013 -0400
    55.3 @@ -86,7 +86,7 @@
    55.4  	}
    55.5  	else
    55.6  	{
    55.7 -		llwarns << "----- GL WARNING -------" << llendl;		
    55.8 +		llwarns << "----- GL WARNING -------" << llendl;
    55.9  	}
   55.10  	llwarns << "Type: " << std::hex << type << llendl;
   55.11  	llwarns << "ID: " << std::hex << id << llendl;
   55.12 @@ -216,6 +216,11 @@
   55.13  PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB = NULL;
   55.14  PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB = NULL;
   55.15  
   55.16 +// GL_ARB_timer_query
   55.17 +PFNGLQUERYCOUNTERPROC glQueryCounter = NULL;
   55.18 +PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v = NULL;
   55.19 +PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v = NULL;
   55.20 +
   55.21  // GL_ARB_point_parameters
   55.22  PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB = NULL;
   55.23  PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB = NULL;
   55.24 @@ -421,6 +426,7 @@
   55.25  	mHasFragmentShader(FALSE),
   55.26  	mNumTextureImageUnits(0),
   55.27  	mHasOcclusionQuery(FALSE),
   55.28 +	mHasTimerQuery(FALSE),
   55.29  	mHasOcclusionQuery2(FALSE),
   55.30  	mHasPointParameters(FALSE),
   55.31  	mHasDrawBuffers(FALSE),
   55.32 @@ -445,7 +451,9 @@
   55.33  	mIsGFFX(FALSE),
   55.34  	mATIOffsetVerticalLines(FALSE),
   55.35  	mATIOldDriver(FALSE),
   55.36 -
   55.37 +#if LL_DARWIN
   55.38 +	mIsMobileGF(FALSE),
   55.39 +#endif
   55.40  	mHasRequirements(TRUE),
   55.41  
   55.42  	mHasSeparateSpecularColor(FALSE),
   55.43 @@ -637,6 +645,13 @@
   55.44  		{
   55.45  			mIsGF3 = TRUE;
   55.46  		}
   55.47 +#if LL_DARWIN
   55.48 +		else if ((mGLRenderer.find("9400M") != std::string::npos)
   55.49 +			  || (mGLRenderer.find("9600M") != std::string::npos))
   55.50 +		{
   55.51 +			mIsMobileGF = TRUE;
   55.52 +		}
   55.53 +#endif
   55.54  
   55.55  	}
   55.56  	else if (mGLVendor.find("INTEL") != std::string::npos
   55.57 @@ -745,12 +760,13 @@
   55.58  	{ //using multisample textures on ATI results in black screen for some reason
   55.59  		mHasTextureMultisample = FALSE;
   55.60  	}
   55.61 -#endif
   55.62 +
   55.63  
   55.64  	if (mIsIntel && mGLVersion <= 3.f)
   55.65  	{ //never try to use framebuffer objects on older intel drivers (crashy)
   55.66  		mHasFramebufferObject = FALSE;
   55.67  	}
   55.68 +#endif
   55.69  
   55.70  	if (mHasFramebufferObject)
   55.71  	{
   55.72 @@ -947,13 +963,15 @@
   55.73  	mHasARBEnvCombine = ExtensionExists("GL_ARB_texture_env_combine", gGLHExts.mSysExts);
   55.74  	mHasCompressedTextures = glh_init_extensions("GL_ARB_texture_compression");
   55.75  	mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);
   55.76 +	mHasTimerQuery = ExtensionExists("GL_ARB_timer_query", gGLHExts.mSysExts);
   55.77  	mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts);
   55.78  	mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
   55.79  	mHasVertexArrayObject = ExtensionExists("GL_ARB_vertex_array_object", gGLHExts.mSysExts);
   55.80  	mHasSync = ExtensionExists("GL_ARB_sync", gGLHExts.mSysExts);
   55.81  	mHasMapBufferRange = ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts);
   55.82  	mHasFlushBufferRange = ExtensionExists("GL_APPLE_flush_buffer_range", gGLHExts.mSysExts);
   55.83 -	mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
   55.84 +	//mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
   55.85 +	mHasDepthClamp = FALSE;
   55.86  	// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad
   55.87  #ifdef GL_ARB_framebuffer_object
   55.88  	mHasFramebufferObject = ExtensionExists("GL_ARB_framebuffer_object", gGLHExts.mSysExts);
   55.89 @@ -963,6 +981,15 @@
   55.90  							ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts) &&
   55.91  							ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
   55.92  #endif
   55.93 +#ifdef GL_EXT_texture_sRGB
   55.94 +	mHassRGBTexture = ExtensionExists("GL_EXT_texture_sRGB", gGLHExts.mSysExts);
   55.95 +#endif
   55.96 +	
   55.97 +#ifdef GL_ARB_framebuffer_sRGB
   55.98 +	mHassRGBFramebuffer = ExtensionExists("GL_ARB_framebuffer_sRGB", gGLHExts.mSysExts);
   55.99 +#else
  55.100 +	mHassRGBFramebuffer = ExtensionExists("GL_EXT_framebuffer_sRGB", gGLHExts.mSysExts);
  55.101 +#endif
  55.102  	
  55.103  	mHasMipMapGeneration = mHasFramebufferObject || mGLVersion >= 1.4f;
  55.104  
  55.105 @@ -1253,6 +1280,13 @@
  55.106  		glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectivARB");
  55.107  		glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectuivARB");
  55.108  	}
  55.109 +	if (mHasTimerQuery)
  55.110 +	{
  55.111 +		llinfos << "initExtensions() TimerQuery-related procs..." << llendl;
  55.112 +		glQueryCounter = (PFNGLQUERYCOUNTERPROC) GLH_EXT_GET_PROC_ADDRESS("glQueryCounter");
  55.113 +		glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC) GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjecti64v");
  55.114 +		glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC) GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectui64v");
  55.115 +	}
  55.116  	if (mHasPointParameters)
  55.117  	{
  55.118  		llinfos << "initExtensions() PointParameters-related procs..." << llendl;
    56.1 --- a/indra/llrender/llgl.h	Thu Jul 18 15:14:55 2013 -0400
    56.2 +++ b/indra/llrender/llgl.h	Thu Jul 18 18:43:58 2013 -0400
    56.3 @@ -98,6 +98,7 @@
    56.4  	BOOL mHasFragmentShader;
    56.5  	S32  mNumTextureImageUnits;
    56.6  	BOOL mHasOcclusionQuery;
    56.7 +	BOOL mHasTimerQuery;
    56.8  	BOOL mHasOcclusionQuery2;
    56.9  	BOOL mHasPointParameters;
   56.10  	BOOL mHasDrawBuffers;
   56.11 @@ -115,6 +116,8 @@
   56.12  	BOOL mHasARBEnvCombine;
   56.13  	BOOL mHasCubeMap;
   56.14  	BOOL mHasDebugOutput;
   56.15 +	BOOL mHassRGBTexture;
   56.16 +	BOOL mHassRGBFramebuffer;
   56.17  
   56.18  	// Vendor-specific extensions
   56.19  	BOOL mIsATI;
   56.20 @@ -126,6 +129,11 @@
   56.21  	BOOL mATIOffsetVerticalLines;
   56.22  	BOOL mATIOldDriver;
   56.23  
   56.24 +#if LL_DARWIN
   56.25 +	// Needed to distinguish problem cards on older Macs that break with Materials
   56.26 +	BOOL mIsMobileGF;
   56.27 +#endif
   56.28 +	
   56.29  	// Whether this version of GL is good enough for SL to use
   56.30  	BOOL mHasRequirements;
   56.31  
    57.1 --- a/indra/llrender/llglheaders.h	Thu Jul 18 15:14:55 2013 -0400
    57.2 +++ b/indra/llrender/llglheaders.h	Thu Jul 18 18:43:58 2013 -0400
    57.3 @@ -116,6 +116,11 @@
    57.4  extern PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB;
    57.5  extern PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB;
    57.6  
    57.7 +// GL_ARB_timer_query
    57.8 +extern PFNGLQUERYCOUNTERPROC glQueryCounter;
    57.9 +extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v;
   57.10 +extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v;
   57.11 +
   57.12  // GL_ARB_point_parameters
   57.13  extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;
   57.14  extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;
   57.15 @@ -378,6 +383,11 @@
   57.16  extern PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB;
   57.17  extern PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB;
   57.18  
   57.19 +// GL_ARB_timer_query
   57.20 +extern PFNGLQUERYCOUNTERPROC glQueryCounter;
   57.21 +extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v;
   57.22 +extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v;
   57.23 +
   57.24  // GL_ARB_point_parameters
   57.25  extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;
   57.26  extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;
   57.27 @@ -619,6 +629,12 @@
   57.28  extern PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB;
   57.29  extern PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB;
   57.30  
   57.31 +// GL_ARB_timer_query
   57.32 +extern PFNGLQUERYCOUNTERPROC glQueryCounter;
   57.33 +extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v;
   57.34 +extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v;
   57.35 +
   57.36 +
   57.37  // GL_ARB_point_parameters
   57.38  extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;
   57.39  extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;
    58.1 --- a/indra/llrender/llglslshader.cpp	Thu Jul 18 15:14:55 2013 -0400
    58.2 +++ b/indra/llrender/llglslshader.cpp	Thu Jul 18 18:43:58 2013 -0400
    58.3 @@ -53,6 +53,12 @@
    58.4  LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL;
    58.5  S32 LLGLSLShader::sIndexedTextureChannels = 0;
    58.6  bool LLGLSLShader::sNoFixedFunction = false;
    58.7 +bool LLGLSLShader::sProfileEnabled = false;
    58.8 +std::set<LLGLSLShader*> LLGLSLShader::sInstances;
    58.9 +U64 LLGLSLShader::sTotalTimeElapsed = 0;
   58.10 +U32 LLGLSLShader::sTotalTrianglesDrawn = 0;
   58.11 +U64 LLGLSLShader::sTotalSamplesDrawn = 0;
   58.12 +U32 LLGLSLShader::sTotalDrawCalls = 0;
   58.13  
   58.14  //UI shader -- declared here so llui_libtest will link properly
   58.15  LLGLSLShader	gUIProgram;
   58.16 @@ -87,19 +93,240 @@
   58.17  //===============================
   58.18  // LLGLSL Shader implementation
   58.19  //===============================
   58.20 +
   58.21 +//static
   58.22 +void LLGLSLShader::initProfile()
   58.23 +{
   58.24 +	sProfileEnabled = true;
   58.25 +	sTotalTimeElapsed = 0;
   58.26 +	sTotalTrianglesDrawn = 0;
   58.27 +	sTotalSamplesDrawn = 0;
   58.28 +	sTotalDrawCalls = 0;
   58.29 +
   58.30 +	for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
   58.31 +	{
   58.32 +		(*iter)->clearStats();
   58.33 +	}
   58.34 +}
   58.35 +
   58.36 +
   58.37 +struct LLGLSLShaderCompareTimeElapsed
   58.38 +{
   58.39 +		bool operator()(const LLGLSLShader* const& lhs, const LLGLSLShader* const& rhs)
   58.40 +		{
   58.41 +			return lhs->mTimeElapsed < rhs->mTimeElapsed;
   58.42 +		}
   58.43 +};
   58.44 +
   58.45 +//static
   58.46 +void LLGLSLShader::finishProfile()
   58.47 +{
   58.48 +	sProfileEnabled = false;
   58.49 +
   58.50 +	std::vector<LLGLSLShader*> sorted;
   58.51 +
   58.52 +	for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
   58.53 +	{
   58.54 +		sorted.push_back(*iter);
   58.55 +	}
   58.56 +
   58.57 +	std::sort(sorted.begin(), sorted.end(), LLGLSLShaderCompareTimeElapsed());
   58.58 +
   58.59 +	for (std::vector<LLGLSLShader*>::iterator iter = sorted.begin(); iter != sorted.end(); ++iter)
   58.60 +	{
   58.61 +		(*iter)->dumpStats();
   58.62 +	}
   58.63 +
   58.64 +	llinfos << "-----------------------------------" << llendl;
   58.65 +	llinfos << "Total rendering time: " << llformat("%.4f ms", sTotalTimeElapsed/1000000.f) << llendl;
   58.66 +	llinfos << "Total samples drawn: " << llformat("%.4f million", sTotalSamplesDrawn/1000000.f) << llendl;
   58.67 +	llinfos << "Total triangles drawn: " << llformat("%.3f million", sTotalTrianglesDrawn/1000000.f) << llendl;
   58.68 +}
   58.69 +
   58.70 +void LLGLSLShader::clearStats()
   58.71 +{
   58.72 +	mTrianglesDrawn = 0;
   58.73 +	mTimeElapsed = 0;
   58.74 +	mSamplesDrawn = 0;
   58.75 +	mDrawCalls = 0;
   58.76 +	mTextureStateFetched = false;
   58.77 +	mTextureMagFilter.clear();
   58.78 +	mTextureMinFilter.clear();
   58.79 +}
   58.80 +
   58.81 +void LLGLSLShader::dumpStats()
   58.82 +{
   58.83 +	if (mDrawCalls > 0)
   58.84 +	{
   58.85 +		llinfos << "=============================================" << llendl;
   58.86 +		llinfos << mName << llendl;
   58.87 +		for (U32 i = 0; i < mShaderFiles.size(); ++i)
   58.88 +		{
   58.89 +			llinfos << mShaderFiles[i].first << llendl;
   58.90 +		}
   58.91 +		for (U32 i = 0; i < mTexture.size(); ++i)
   58.92 +		{
   58.93 +			GLint idx = mTexture[i];
   58.94 +			
   58.95 +			if (idx >= 0)
   58.96 +			{
   58.97 +				GLint uniform_idx = getUniformLocation(i);
   58.98 +				llinfos << mUniformNameMap[uniform_idx] << " - " << std::hex << mTextureMagFilter[i] << "/" << mTextureMinFilter[i] << std::dec << llendl;
   58.99 +			}
  58.100 +		}
  58.101 +		llinfos << "=============================================" << llendl;
  58.102 +
  58.103 +		F32 ms = mTimeElapsed/1000000.f;
  58.104 +		F32 seconds = ms/1000.f;
  58.105 +
  58.106 +		F32 pct_tris = (F32) mTrianglesDrawn/(F32)sTotalTrianglesDrawn*100.f;
  58.107 +		F32 tris_sec = (F32) (mTrianglesDrawn/1000000.0);
  58.108 +		tris_sec /= seconds;
  58.109 +
  58.110 +		F32 pct_samples = (F32) ((F64)mSamplesDrawn/(F64)sTotalSamplesDrawn)*100.f;
  58.111 +		F32 samples_sec = (F32) mSamplesDrawn/1000000000.0;
  58.112 +		samples_sec /= seconds;
  58.113 +
  58.114 +		F32 pct_calls = (F32) mDrawCalls/(F32)sTotalDrawCalls*100.f;
  58.115 +		U32 avg_batch = mTrianglesDrawn/mDrawCalls;
  58.116 +
  58.117 +		llinfos << "Triangles Drawn: " << mTrianglesDrawn <<  " " << llformat("(%.2f pct of total, %.3f million/sec)", pct_tris, tris_sec ) << llendl;
  58.118 +		llinfos << "Draw Calls: " << mDrawCalls << " " << llformat("(%.2f pct of total, avg %d tris/call)", pct_calls, avg_batch) << llendl;
  58.119 +		llinfos << "SamplesDrawn: " << mSamplesDrawn << " " << llformat("(%.2f pct of total, %.3f billion/sec)", pct_samples, samples_sec) << llendl;
  58.120 +		llinfos << "Time Elapsed: " << mTimeElapsed << " " << llformat("(%.2f pct of total, %.5f ms)\n", (F32) ((F64)mTimeElapsed/(F64)sTotalTimeElapsed)*100.f, ms) << llendl;
  58.121 +	}
  58.122 +}
  58.123 +
  58.124 +//static
  58.125 +void LLGLSLShader::startProfile()
  58.126 +{
  58.127 +	if (sProfileEnabled && sCurBoundShaderPtr)
  58.128 +	{
  58.129 +		sCurBoundShaderPtr->placeProfileQuery();
  58.130 +	}
  58.131 +
  58.132 +}
  58.133 +
  58.134 +//static
  58.135 +void LLGLSLShader::stopProfile(U32 count, U32 mode)
  58.136 +{
  58.137 +	if (sProfileEnabled)
  58.138 +	{
  58.139 +		sCurBoundShaderPtr->readProfileQuery(count, mode);
  58.140 +	}
  58.141 +}
  58.142 +
  58.143 +void LLGLSLShader::placeProfileQuery()
  58.144 +{
  58.145 +#if !LL_DARWIN
  58.146 +	if (mTimerQuery == 0)
  58.147 +	{
  58.148 +		glGenQueriesARB(1, &mTimerQuery);
  58.149 +	}
  58.150 +
  58.151 +	if (!mTextureStateFetched)
  58.152 +	{
  58.153 +		mTextureStateFetched = true;
  58.154 +		mTextureMagFilter.resize(mTexture.size());
  58.155 +		mTextureMinFilter.resize(mTexture.size());
  58.156 +
  58.157 +		U32 cur_active = gGL.getCurrentTexUnitIndex();
  58.158 +
  58.159 +		for (U32 i = 0; i < mTexture.size(); ++i)
  58.160 +		{
  58.161 +			GLint idx = mTexture[i];
  58.162 +
  58.163 +			if (idx >= 0)
  58.164 +			{
  58.165 +				gGL.getTexUnit(idx)->activate();
  58.166 +
  58.167 +				U32 mag = 0xFFFFFFFF;
  58.168 +				U32 min = 0xFFFFFFFF;
  58.169 +
  58.170 +				U32 type = LLTexUnit::getInternalType(gGL.getTexUnit(idx)->getCurrType());
  58.171 +
  58.172 +				glGetTexParameteriv(type, GL_TEXTURE_MAG_FILTER, (GLint*) &mag);
  58.173 +				glGetTexParameteriv(type, GL_TEXTURE_MIN_FILTER, (GLint*) &min);
  58.174 +
  58.175 +				mTextureMagFilter[i] = mag;
  58.176 +				mTextureMinFilter[i] = min;
  58.177 +			}
  58.178 +		}
  58.179 +
  58.180 +		gGL.getTexUnit(cur_active)->activate();
  58.181 +	}
  58.182 +
  58.183 +
  58.184 +	glBeginQueryARB(GL_SAMPLES_PASSED, 1);
  58.185 +	glBeginQueryARB(GL_TIME_ELAPSED, mTimerQuery);
  58.186 +#endif
  58.187 +}
  58.188 +
  58.189 +void LLGLSLShader::readProfileQuery(U32 count, U32 mode)
  58.190 +{
  58.191 +#if !LL_DARWIN
  58.192 +	glEndQueryARB(GL_TIME_ELAPSED);
  58.193 +	glEndQueryARB(GL_SAMPLES_PASSED);
  58.194 +	
  58.195 +	U64 time_elapsed = 0;
  58.196 +	glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT, &time_elapsed);
  58.197 +
  58.198 +	U64 samples_passed = 0;
  58.199 +	glGetQueryObjectui64v(1, GL_QUERY_RESULT, &samples_passed);
  58.200 +
  58.201 +	sTotalTimeElapsed += time_elapsed;
  58.202 +	mTimeElapsed += time_elapsed;
  58.203 +
  58.204 +	sTotalSamplesDrawn += samples_passed;
  58.205 +	mSamplesDrawn += samples_passed;
  58.206 +
  58.207 +	U32 tri_count = 0;
  58.208 +	switch (mode)
  58.209 +	{
  58.210 +		case LLRender::TRIANGLES: tri_count = count/3; break;
  58.211 +		case LLRender::TRIANGLE_FAN: tri_count = count-2; break;
  58.212 +		case LLRender::TRIANGLE_STRIP: tri_count = count-2; break;
  58.213 +		default: tri_count = count; break; //points lines etc just use primitive count
  58.214 +	}
  58.215 +
  58.216 +	mTrianglesDrawn += tri_count;
  58.217 +	sTotalTrianglesDrawn += tri_count;
  58.218 +
  58.219 +	sTotalDrawCalls++;
  58.220 +	mDrawCalls++;
  58.221 +#endif
  58.222 +}
  58.223 +
  58.224 +
  58.225 +
  58.226  LLGLSLShader::LLGLSLShader()
  58.227 -	: mProgramObject(0), mActiveTextureChannels(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT), mUniformsDirty(FALSE)
  58.228 +	: mProgramObject(0), 
  58.229 +	  mAttributeMask(0),
  58.230 +	  mTotalUniformSize(0),
  58.231 +	  mActiveTextureChannels(0), 
  58.232 +	  mShaderLevel(0), 
  58.233 +	  mShaderGroup(SG_DEFAULT), 
  58.234 +	  mUniformsDirty(FALSE),
  58.235 +	  mTimerQuery(0)
  58.236  {
  58.237 +	
  58.238 +}
  58.239  
  58.240 +LLGLSLShader::~LLGLSLShader()
  58.241 +{
  58.242 +	
  58.243  }
  58.244  
  58.245  void LLGLSLShader::unload()
  58.246  {
  58.247 +	sInstances.erase(this);
  58.248 +
  58.249  	stop_glerror();
  58.250  	mAttribute.clear();
  58.251  	mTexture.clear();
  58.252  	mUniform.clear();
  58.253  	mShaderFiles.clear();
  58.254 +	mDefines.clear();
  58.255  
  58.256  	if (mProgramObject)
  58.257  	{
  58.258 @@ -133,6 +360,8 @@
  58.259  								U32 varying_count,
  58.260  								const char** varyings)
  58.261  {
  58.262 +	sInstances.insert(this);
  58.263 +
  58.264  	//reloading, reset matrix hash values
  58.265  	for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i)
  58.266  	{
  58.267 @@ -150,7 +379,7 @@
  58.268  	vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
  58.269  	for ( ; fileIter != mShaderFiles.end(); fileIter++ )
  58.270  	{
  58.271 -		GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, mFeatures.mIndexedTextureChannels);
  58.272 +		GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, &mDefines, mFeatures.mIndexedTextureChannels);
  58.273  		LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
  58.274  		if (shaderhandle > 0)
  58.275  		{
  58.276 @@ -285,6 +514,8 @@
  58.277  	if (res)
  58.278  	{ //read back channel locations
  58.279  
  58.280 +		mAttributeMask = 0;
  58.281 +
  58.282  		//read back reserved channels first
  58.283  		for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
  58.284  		{
  58.285 @@ -293,6 +524,7 @@
  58.286  			if (index != -1)
  58.287  			{
  58.288  				mAttribute[i] = index;
  58.289 +				mAttributeMask |= 1 << i;
  58.290  				LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
  58.291  			}
  58.292  		}
  58.293 @@ -325,11 +557,56 @@
  58.294  
  58.295  	GLenum type;
  58.296  	GLsizei length;
  58.297 -	GLint size;
  58.298 +	GLint size = -1;
  58.299  	char name[1024];		/* Flawfinder: ignore */
  58.300  	name[0] = 0;
  58.301  
  58.302 +
  58.303  	glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name);
  58.304 +#if !LL_DARWIN
  58.305 +	if (size > 0)
  58.306 +	{
  58.307 +		switch(type)
  58.308 +		{
  58.309 +			case GL_FLOAT_VEC2: size *= 2; break;
  58.310 +			case GL_FLOAT_VEC3: size *= 3; break;
  58.311 +			case GL_FLOAT_VEC4: size *= 4; break;
  58.312 +			case GL_DOUBLE: size *= 2; break;
  58.313 +			case GL_DOUBLE_VEC2: size *= 2; break;
  58.314 +			case GL_DOUBLE_VEC3: size *= 6; break;
  58.315 +			case GL_DOUBLE_VEC4: size *= 8; break;
  58.316 +			case GL_INT_VEC2: size *= 2; break;
  58.317 +			case GL_INT_VEC3: size *= 3; break;
  58.318 +			case GL_INT_VEC4: size *= 4; break;
  58.319 +			case GL_UNSIGNED_INT_VEC2: size *= 2; break;
  58.320 +			case GL_UNSIGNED_INT_VEC3: size *= 3; break;
  58.321 +			case GL_UNSIGNED_INT_VEC4: size *= 4; break;
  58.322 +			case GL_BOOL_VEC2: size *= 2; break;
  58.323 +			case GL_BOOL_VEC3: size *= 3; break;
  58.324 +			case GL_BOOL_VEC4: size *= 4; break;
  58.325 +			case GL_FLOAT_MAT2: size *= 4; break;
  58.326 +			case GL_FLOAT_MAT3: size *= 9; break;
  58.327 +			case GL_FLOAT_MAT4: size *= 16; break;
  58.328 +			case GL_FLOAT_MAT2x3: size *= 6; break;
  58.329 +			case GL_FLOAT_MAT2x4: size *= 8; break;
  58.330 +			case GL_FLOAT_MAT3x2: size *= 6; break;
  58.331 +			case GL_FLOAT_MAT3x4: size *= 12; break;
  58.332 +			case GL_FLOAT_MAT4x2: size *= 8; break;
  58.333 +			case GL_FLOAT_MAT4x3: size *= 12; break;
  58.334 +			case GL_DOUBLE_MAT2: size *= 8; break;
  58.335 +			case GL_DOUBLE_MAT3: size *= 18; break;
  58.336 +			case GL_DOUBLE_MAT4: size *= 32; break;
  58.337 +			case GL_DOUBLE_MAT2x3: size *= 12; break;
  58.338 +			case GL_DOUBLE_MAT2x4: size *= 16; break;
  58.339 +			case GL_DOUBLE_MAT3x2: size *= 12; break;
  58.340 +			case GL_DOUBLE_MAT3x4: size *= 24; break;
  58.341 +			case GL_DOUBLE_MAT4x2: size *= 16; break;
  58.342 +			case GL_DOUBLE_MAT4x3: size *= 24; break;
  58.343 +		}
  58.344 +		mTotalUniformSize += size;
  58.345 +	}
  58.346 +#endif
  58.347 +
  58.348  	S32 location = glGetUniformLocationARB(mProgramObject, name);
  58.349  	if (location != -1)
  58.350  	{
  58.351 @@ -342,6 +619,7 @@
  58.352  		}
  58.353  
  58.354  		mUniformMap[name] = location;
  58.355 +		mUniformNameMap[location] = name;
  58.356  		LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL;
  58.357  	
  58.358  		//find the index of this uniform
  58.359 @@ -372,11 +650,21 @@
  58.360  			}
  58.361  		}
  58.362  	}
  58.363 - }
  58.364 +}
  58.365 +
  58.366 +void LLGLSLShader::addPermutation(std::string name, std::string value)
  58.367 +{
  58.368 +	mDefines[name] = value;
  58.369 +}
  58.370 +
  58.371 +void LLGLSLShader::removePermutation(std::string name)
  58.372 +{
  58.373 +	mDefines[name].erase();
  58.374 +}
  58.375  
  58.376  GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
  58.377  {
  58.378 -	if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB ||
  58.379 +	if ((type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) ||
  58.380  		type == GL_SAMPLER_2D_MULTISAMPLE)
  58.381  	{	//this here is a texture
  58.382  		glUniform1iARB(location, mActiveTextureChannels);
  58.383 @@ -390,9 +678,11 @@
  58.384  {
  58.385  	BOOL res = TRUE;
  58.386  	
  58.387 +	mTotalUniformSize = 0;
  58.388  	mActiveTextureChannels = 0;
  58.389  	mUniform.clear();
  58.390  	mUniformMap.clear();
  58.391 +	mUniformNameMap.clear();
  58.392  	mTexture.clear();
  58.393  	mValue.clear();
  58.394  	//initialize arrays
  58.395 @@ -413,6 +703,7 @@
  58.396  
  58.397  	unbind();
  58.398  
  58.399 +	LL_DEBUGS("ShaderLoading") << "Total Uniform Size: " << mTotalUniformSize << llendl;
  58.400  	return res;
  58.401  }
  58.402  
  58.403 @@ -471,6 +762,58 @@
  58.404  	}
  58.405  }
  58.406  
  58.407 +S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode)
  58.408 +{
  58.409 +	S32 channel = 0;
  58.410 +	channel = getUniformLocation(uniform);
  58.411 +	
  58.412 +	return bindTexture(channel, texture, mode);
  58.413 +}
  58.414 +
  58.415 +S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode)
  58.416 +{
  58.417 +	if (uniform < 0 || uniform >= (S32)mTexture.size())
  58.418 +	{
  58.419 +		UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
  58.420 +		return -1;
  58.421 +	}
  58.422 +	
  58.423 +	uniform = mTexture[uniform];
  58.424 +	
  58.425 +	if (uniform > -1)
  58.426 +	{
  58.427 +		gGL.getTexUnit(uniform)->bind(texture, mode);
  58.428 +	}
  58.429 +	
  58.430 +	return uniform;
  58.431 +}
  58.432 +
  58.433 +S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureType mode)
  58.434 +{
  58.435 +	S32 channel = 0;
  58.436 +	channel = getUniformLocation(uniform);
  58.437 +	
  58.438 +	return unbindTexture(channel);
  58.439 +}
  58.440 +
  58.441 +S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
  58.442 +{
  58.443 +	if (uniform < 0 || uniform >= (S32)mTexture.size())
  58.444 +	{
  58.445 +		UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
  58.446 +		return -1;
  58.447 +	}
  58.448 +	
  58.449 +	uniform = mTexture[uniform];
  58.450 +	
  58.451 +	if (uniform > -1)
  58.452 +	{
  58.453 +		gGL.getTexUnit(uniform)->unbind(mode);
  58.454 +	}
  58.455 +	
  58.456 +	return uniform;
  58.457 +}
  58.458 +
  58.459  S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
  58.460  {
  58.461  	if (uniform < 0 || uniform >= (S32)mTexture.size())
  58.462 @@ -857,6 +1200,23 @@
  58.463  	}
  58.464  }
  58.465  
  58.466 +void LLGLSLShader::uniform2i(const string& uniform, GLint i, GLint j)
  58.467 +{
  58.468 +	GLint location = getUniformLocation(uniform);
  58.469 +				
  58.470 +	if (location >= 0)
  58.471 +	{
  58.472 +		std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
  58.473 +		LLVector4 vec(i,j,0.f,0.f);
  58.474 +		if (iter == mValue.end() || shouldChange(iter->second,vec))
  58.475 +		{
  58.476 +			glUniform2iARB(location, i, j);
  58.477 +			mValue[location] = vec;
  58.478 +		}
  58.479 +	}
  58.480 +}
  58.481 +
  58.482 +
  58.483  void LLGLSLShader::uniform1f(const string& uniform, GLfloat v)
  58.484  {
  58.485  	GLint location = getUniformLocation(uniform);
    59.1 --- a/indra/llrender/llglslshader.h	Thu Jul 18 15:14:55 2013 -0400
    59.2 +++ b/indra/llrender/llglslshader.h	Thu Jul 18 18:43:58 2013 -0400
    59.3 @@ -67,14 +67,29 @@
    59.4  		SG_WATER
    59.5  	};
    59.6  	
    59.7 +	static std::set<LLGLSLShader*> sInstances;
    59.8 +	static bool sProfileEnabled;
    59.9 +
   59.10  	LLGLSLShader();
   59.11 +	~LLGLSLShader();
   59.12  
   59.13  	static GLhandleARB sCurBoundShader;
   59.14  	static LLGLSLShader* sCurBoundShaderPtr;
   59.15  	static S32 sIndexedTextureChannels;
   59.16  	static bool sNoFixedFunction;
   59.17  
   59.18 +	static void initProfile();
   59.19 +	static void finishProfile();
   59.20 +
   59.21 +	static void startProfile();
   59.22 +	static void stopProfile(U32 count, U32 mode);
   59.23 +
   59.24  	void unload();
   59.25 +	void clearStats();
   59.26 +	void dumpStats();
   59.27 +	void placeProfileQuery();
   59.28 +	void readProfileQuery(U32 count, U32 mode);
   59.29 +
   59.30  	BOOL createShader(std::vector<std::string> * attributes,
   59.31  						std::vector<std::string> * uniforms,
   59.32  						U32 varying_count = 0,
   59.33 @@ -96,6 +111,7 @@
   59.34  	void uniform3fv(U32 index, U32 count, const GLfloat* v);
   59.35  	void uniform4fv(U32 index, U32 count, const GLfloat* v);
   59.36  	void uniform1i(const std::string& uniform, GLint i);
   59.37 +	void uniform2i(const std::string& uniform, GLint i, GLint j);
   59.38  	void uniform1f(const std::string& uniform, GLfloat v);
   59.39  	void uniform2f(const std::string& uniform, GLfloat x, GLfloat y);
   59.40  	void uniform3f(const std::string& uniform, GLfloat x, GLfloat y, GLfloat z);
   59.41 @@ -123,12 +139,22 @@
   59.42  	GLint getAttribLocation(U32 attrib);
   59.43  	GLint mapUniformTextureChannel(GLint location, GLenum type);
   59.44  	
   59.45 +	void addPermutation(std::string name, std::string value);
   59.46 +	void removePermutation(std::string name);
   59.47 +	
   59.48  	//enable/disable texture channel for specified uniform
   59.49  	//if given texture uniform is active in the shader, 
   59.50  	//the corresponding channel will be active upon return
   59.51  	//returns channel texture is enabled in from [0-MAX)
   59.52  	S32 enableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
   59.53 -	S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE); 
   59.54 +	S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
   59.55 +	
   59.56 +	// bindTexture returns the texture unit we've bound the texture to.
   59.57 +	// You can reuse the return value to unbind a texture when required.
   59.58 +	S32 bindTexture(const std::string& uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
   59.59 +	S32 bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
   59.60 +	S32 unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
   59.61 +	S32 unbindTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
   59.62  	
   59.63      BOOL link(BOOL suppress_errors = FALSE);
   59.64  	void bind();
   59.65 @@ -142,10 +168,13 @@
   59.66  
   59.67  	GLhandleARB mProgramObject;
   59.68  	std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel
   59.69 +	U32 mAttributeMask;  //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())
   59.70  	std::vector<GLint> mUniform;   //lookup table of uniform enum to uniform location
   59.71  	std::map<std::string, GLint> mUniformMap;  //lookup map of uniform name to uniform location
   59.72 +	std::map<GLint, std::string> mUniformNameMap; //lookup map of uniform location to uniform name
   59.73  	std::map<GLint, LLVector4> mValue; //lookup map of uniform location to last known value
   59.74  	std::vector<GLint> mTexture;
   59.75 +	S32 mTotalUniformSize;
   59.76  	S32 mActiveTextureChannels;
   59.77  	S32 mShaderLevel;
   59.78  	S32 mShaderGroup;
   59.79 @@ -153,6 +182,23 @@
   59.80  	LLShaderFeatures mFeatures;
   59.81  	std::vector< std::pair< std::string, GLenum > > mShaderFiles;
   59.82  	std::string mName;
   59.83 +	boost::unordered_map<std::string, std::string> mDefines;
   59.84 +
   59.85 +	//statistcis for profiling shader performance
   59.86 +	U32 mTimerQuery;
   59.87 +	U64 mTimeElapsed;
   59.88 +	static U64 sTotalTimeElapsed;
   59.89 +	U32 mTrianglesDrawn;
   59.90 +	static U32 sTotalTrianglesDrawn;
   59.91 +	U64 mSamplesDrawn;
   59.92 +	static U64 sTotalSamplesDrawn;
   59.93 +	U32 mDrawCalls;
   59.94 +	static U32 sTotalDrawCalls;
   59.95 +
   59.96 +	bool mTextureStateFetched;
   59.97 +	std::vector<U32> mTextureMagFilter;
   59.98 +	std::vector<U32> mTextureMinFilter;
   59.99 +	
  59.100  };
  59.101  
  59.102  //UI shader (declared here so llui_libtest will link properly)
    60.1 --- a/indra/llrender/llimagegl.cpp	Thu Jul 18 15:14:55 2013 -0400
    60.2 +++ b/indra/llrender/llimagegl.cpp	Thu Jul 18 18:43:58 2013 -0400
    60.3 @@ -748,12 +748,16 @@
    60.4  				S32 height = getHeight(mCurrentDiscardLevel);
    60.5  				S32 nummips = mMaxDiscardLevel - mCurrentDiscardLevel + 1;
    60.6  				S32 w = width, h = height;
    60.7 +
    60.8 +
    60.9 +				const U8* new_data = 0;
   60.10 +				(void)new_data;
   60.11 +
   60.12  				const U8* prev_mip_data = 0;
   60.13  				const U8* cur_mip_data = 0;
   60.14  #ifdef SHOW_ASSERT
   60.15  				S32 cur_mip_size = 0;
   60.16  #endif
   60.17 -				
   60.18  				mMipLevels = nummips;
   60.19  
   60.20  				for (int m=0; m<nummips; m++)
   60.21 @@ -773,14 +777,22 @@
   60.22  						llassert(cur_mip_size == bytes*4);
   60.23  #endif
   60.24  						U8* new_data = new U8[bytes];
   60.25 +
   60.26 +#ifdef SHOW_ASSERT
   60.27 +						llassert(prev_mip_data);
   60.28 +						llassert(cur_mip_size == bytes*4);
   60.29  						llassert_always(new_data);
   60.30 +#endif
   60.31 +
   60.32  						LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);
   60.33  						cur_mip_data = new_data;
   60.34  #ifdef SHOW_ASSERT
   60.35  						cur_mip_size = bytes; 
   60.36  #endif
   60.37 +
   60.38  					}
   60.39  					llassert(w > 0 && h > 0 && cur_mip_data);
   60.40 +					(void)cur_mip_data;
   60.41  					{
   60.42  // 						LLFastTimer t1(FTM_TEMP4);
   60.43  						if(mFormatSwapBytes)
   60.44 @@ -1119,30 +1131,30 @@
   60.45  			default:
   60.46  			{
   60.47  				if (type == LLTexUnit::TT_CUBE_MAP || mip_levels == -1)
   60.48 -				{ //unknown internal format or unknown number of mip levels, not safe to reuse
   60.49 -					glDeleteTextures(numTextures, textures);
   60.50 -				}
   60.51 -				else
   60.52 +		{ //unknown internal format or unknown number of mip levels, not safe to reuse
   60.53 +			glDeleteTextures(numTextures, textures);
   60.54 +		}
   60.55 +		else
   60.56 +		{
   60.57 +			for (S32 i = 0; i < numTextures; ++i)
   60.58 +			{ //remove texture from VRAM by setting its size to zero
   60.59 +
   60.60 +				for (S32 j = 0; j <= mip_levels; j++)
   60.61  				{
   60.62 -					for (S32 i = 0; i < numTextures; ++i)
   60.63 -					{ //remove texture from VRAM by setting its size to zero
   60.64 -
   60.65 -						for (S32 j = 0; j <= mip_levels; j++)
   60.66 -						{
   60.67 -							gGL.getTexUnit(0)->bindManual(type, textures[i]);
   60.68 +					gGL.getTexUnit(0)->bindManual(type, textures[i]);
   60.69  							U32 internal_type = LLTexUnit::getInternalType(type);
   60.70  							glTexImage2D(internal_type, j, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
   60.71  							stop_glerror();
   60.72 -						}
   60.73 +				}
   60.74  
   60.75 -						llassert(std::find(sDeadTextureList[type][format].begin(),
   60.76 -							sDeadTextureList[type][format].end(), textures[i]) == 
   60.77 -							sDeadTextureList[type][format].end());
   60.78 +				llassert(std::find(sDeadTextureList[type][format].begin(),
   60.79 +								   sDeadTextureList[type][format].end(), textures[i]) == 
   60.80 +								   sDeadTextureList[type][format].end());
   60.81  
   60.82 -						sDeadTextureList[type][format].push_back(textures[i]);
   60.83 -					}	
   60.84 -				}				
   60.85 -			}
   60.86 +				sDeadTextureList[type][format].push_back(textures[i]);
   60.87 +			}	
   60.88 +		}
   60.89 +	}
   60.90  			break;
   60.91  		}
   60.92  	}
    61.1 --- a/indra/llrender/llrender.h	Thu Jul 18 15:14:55 2013 -0400
    61.2 +++ b/indra/llrender/llrender.h	Thu Jul 18 18:43:58 2013 -0400
    61.3 @@ -262,6 +262,14 @@
    61.4  	friend class LLTexUnit;
    61.5  public:
    61.6  
    61.7 +	enum eTexIndex
    61.8 +	{
    61.9 +		DIFFUSE_MAP = 0,
   61.10 +		NORMAL_MAP,
   61.11 +		SPECULAR_MAP,
   61.12 +		NUM_TEXTURE_CHANNELS,
   61.13 +	};
   61.14 +	
   61.15  	typedef enum {
   61.16  		TRIANGLES = 0,
   61.17  		TRIANGLE_STRIP,
    62.1 --- a/indra/llrender/llrendertarget.cpp	Thu Jul 18 15:14:55 2013 -0400
    62.2 +++ b/indra/llrender/llrendertarget.cpp	Thu Jul 18 18:43:58 2013 -0400
    62.3 @@ -53,11 +53,19 @@
    62.4  bool LLRenderTarget::sUseFBO = false;
    62.5  U32 LLRenderTarget::sCurFBO = 0;
    62.6  
    62.7 +
    62.8 +extern S32 gGLViewport[4];
    62.9 +
   62.10 +U32 LLRenderTarget::sCurResX = 0;
   62.11 +U32 LLRenderTarget::sCurResY = 0;
   62.12 +
   62.13  LLRenderTarget::LLRenderTarget() :
   62.14  	mResX(0),
   62.15  	mResY(0),
   62.16  	mFBO(0),
   62.17  	mPreviousFBO(0),
   62.18 +	mPreviousResX(0),
   62.19 +	mPreviousResY(0),
   62.20  	mDepth(0),
   62.21  	mStencil(0),
   62.22  	mUseDepth(false),
   62.23 @@ -390,13 +398,12 @@
   62.24  {
   62.25  	if (mFBO)
   62.26  	{
   62.27 -		mPreviousFBO = sCurFBO;
   62.28 -
   62.29  		stop_glerror();
   62.30  		
   62.31 +		mPreviousFBO = sCurFBO;
   62.32  		glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
   62.33  		sCurFBO = mFBO;
   62.34 -
   62.35 +		
   62.36  		stop_glerror();
   62.37  		if (gGLManager.mHasDrawBuffers)
   62.38  		{ //setup multiple render targets
   62.39 @@ -418,7 +425,12 @@
   62.40  		stop_glerror();
   62.41  	}
   62.42  
   62.43 +	mPreviousResX = sCurResX;
   62.44 +	mPreviousResY = sCurResY;
   62.45  	glViewport(0, 0, mResX, mResY);
   62.46 +	sCurResX = mResX;
   62.47 +	sCurResY = mResY;
   62.48 +
   62.49  	sBoundTarget = this;
   62.50  }
   62.51  
   62.52 @@ -489,6 +501,20 @@
   62.53  		stop_glerror();
   62.54  		glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFBO);
   62.55  		sCurFBO = mPreviousFBO;
   62.56 +
   62.57 +		if (mPreviousFBO)
   62.58 +		{
   62.59 +			glViewport(0, 0, mPreviousResX, mPreviousResY);
   62.60 +			sCurResX = mPreviousResX;
   62.61 +			sCurResY = mPreviousResY;
   62.62 +		}
   62.63 +		else
   62.64 +		{
   62.65 +			glViewport(gGLViewport[0],gGLViewport[1],gGLViewport[2],gGLViewport[3]);
   62.66 +			sCurResX = gGLViewport[2];
   62.67 +			sCurResY = gGLViewport[3];
   62.68 +		}
   62.69 +						
   62.70  		stop_glerror();
   62.71  	}
   62.72  }
    63.1 --- a/indra/llrender/llrendertarget.h	Thu Jul 18 15:14:55 2013 -0400
    63.2 +++ b/indra/llrender/llrendertarget.h	Thu Jul 18 18:43:58 2013 -0400
    63.3 @@ -63,6 +63,9 @@
    63.4  	static bool sUseFBO; 
    63.5  	static U32 sBytesAllocated;
    63.6  	static U32 sCurFBO;
    63.7 +	static U32 sCurResX;
    63.8 +	static U32 sCurResY;
    63.9 +
   63.10  
   63.11  	LLRenderTarget();
   63.12  	~LLRenderTarget();
   63.13 @@ -146,6 +149,9 @@
   63.14  	std::vector<U32> mInternalFormat;
   63.15  	U32 mFBO;
   63.16  	U32 mPreviousFBO;
   63.17 +	U32 mPreviousResX;
   63.18 +	U32 mPreviousResY;
   63.19 +
   63.20  	U32 mDepth;
   63.21  	bool mStencil;
   63.22  	bool mUseDepth;
    64.1 --- a/indra/llrender/llshadermgr.cpp	Thu Jul 18 15:14:55 2013 -0400
    64.2 +++ b/indra/llrender/llshadermgr.cpp	Thu Jul 18 18:43:58 2013 -0400
    64.3 @@ -521,7 +521,7 @@
    64.4  	}
    64.5   }
    64.6  
    64.7 -GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels)
    64.8 +GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines, S32 texture_index_channels)
    64.9  {
   64.10  	GLenum error = GL_NO_ERROR;
   64.11  	if (gDebugGL)
   64.12 @@ -650,13 +650,15 @@
   64.13  			text[count++] = strdup("#define shadow2DRect(a,b) vec2(texture(a,b))\n");
   64.14  		}
   64.15  	}
   64.16 -
   64.17 -	//copy preprocessor definitions into buffer
   64.18 -	for (std::map<std::string,std::string>::iterator iter = mDefinitions.begin(); iter != mDefinitions.end(); ++iter)
   64.19 +	
   64.20 +	if (defines)
   64.21 +	{
   64.22 +		for (boost::unordered_map<std::string,std::string>::iterator iter = defines->begin(); iter != defines->end(); ++iter)
   64.23  	{
   64.24  		std::string define = "#define " + iter->first + " " + iter->second + "\n";
   64.25  		text[count++] = (GLcharARB *) strdup(define.c_str());
   64.26  	}
   64.27 +	}
   64.28  
   64.29  	if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER_ARB)
   64.30  	{
   64.31 @@ -693,6 +695,8 @@
   64.32  		}
   64.33  		*/
   64.34  
   64.35 +		text[count++] = strdup("#define HAS_DIFFUSE_LOOKUP 1\n");
   64.36 +
   64.37  		//uniform declartion
   64.38  		for (S32 i = 0; i < texture_index_channels; ++i)
   64.39  		{
   64.40 @@ -750,6 +754,10 @@
   64.41  			llerrs << "Indexed texture rendering requires GLSL 1.30 or later." << llendl;
   64.42  		}
   64.43  	}
   64.44 +	else
   64.45 +	{
   64.46 +		text[count++] = strdup("#define HAS_DIFFUSE_LOOKUP 0\n");
   64.47 +	}
   64.48  
   64.49  	//copy file into memory
   64.50  	while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(text) ) 
   64.51 @@ -806,7 +814,6 @@
   64.52  				//an error occured, print log
   64.53  				LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL;
   64.54  				dumpObjectLog(ret);
   64.55 -
   64.56  #if LL_WINDOWS
   64.57  				std::stringstream ostr;
   64.58  				//dump shader source for debugging
   64.59 @@ -824,8 +831,20 @@
   64.60  				}
   64.61  
   64.62  				LL_WARNS("ShaderLoading") << "\n" << ostr.str() << llendl;
   64.63 -#endif // LL_WINDOWS
   64.64 -
   64.65 +#else
   64.66 +				std::string str;
   64.67 +				
   64.68 +				for (GLuint i = 0; i < count; i++) {
   64.69 +					str.append(text[i]);
   64.70 +					
   64.71 +					if (i % 128 == 0)
   64.72 +					{
   64.73 +						LL_WARNS("ShaderLoading") << str << llendl;
   64.74 +						str = "";
   64.75 +					}
   64.76 +				}
   64.77 +#endif
   64.78 +				
   64.79  				ret = 0;
   64.80  			}
   64.81  		}
   64.82 @@ -854,7 +873,7 @@
   64.83  		if (shader_level > 1)
   64.84  		{
   64.85  			shader_level--;
   64.86 -			return loadShaderFile(filename,shader_level,type,texture_index_channels);
   64.87 +			return loadShaderFile(filename,shader_level,type, defines, texture_index_channels);
   64.88  		}
   64.89  		LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;	
   64.90  	}
   64.91 @@ -958,7 +977,7 @@
   64.92  	mReservedAttribs.push_back("texcoord3");
   64.93  	mReservedAttribs.push_back("diffuse_color");
   64.94  	mReservedAttribs.push_back("emissive");
   64.95 -	mReservedAttribs.push_back("binormal");
   64.96 +	mReservedAttribs.push_back("tangent");
   64.97  	mReservedAttribs.push_back("weight");
   64.98  	mReservedAttribs.push_back("weight4");
   64.99  	mReservedAttribs.push_back("clothing");
  64.100 @@ -1055,6 +1074,7 @@
  64.101  
  64.102  
  64.103  	mReservedUniforms.push_back("minimum_alpha");
  64.104 +	mReservedUniforms.push_back("emissive_brightness");
  64.105  
  64.106  	mReservedUniforms.push_back("shadow_matrix");
  64.107  	mReservedUniforms.push_back("env_mat");
  64.108 @@ -1115,6 +1135,12 @@
  64.109  	mReservedUniforms.push_back("lightMap");
  64.110  	mReservedUniforms.push_back("bloomMap");
  64.111  	mReservedUniforms.push_back("projectionMap");
  64.112 +	
  64.113 +	mReservedUniforms.push_back("global_gamma");
  64.114 +	mReservedUniforms.push_back("texture_gamma");
  64.115 +	
  64.116 +	mReservedUniforms.push_back("specular_color");
  64.117 +	mReservedUniforms.push_back("env_intensity");
  64.118  
  64.119  	llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
  64.120  
    65.1 --- a/indra/llrender/llshadermgr.h	Thu Jul 18 15:14:55 2013 -0400
    65.2 +++ b/indra/llrender/llshadermgr.h	Thu Jul 18 18:43:58 2013 -0400
    65.3 @@ -109,6 +109,7 @@
    65.4  		GLOW_DELTA,
    65.5  
    65.6  		MINIMUM_ALPHA,
    65.7 +		EMISSIVE_BRIGHTNESS,
    65.8  
    65.9  		DEFERRED_SHADOW_MATRIX,
   65.10  		DEFERRED_ENV_MAT,
   65.11 @@ -164,6 +165,13 @@
   65.12  		DEFERRED_LIGHT,
   65.13  		DEFERRED_BLOOM,
   65.14  		DEFERRED_PROJECTION,
   65.15 +		
   65.16 +		GLOBAL_GAMMA,
   65.17 +		TEXTURE_GAMMA,
   65.18 +		
   65.19 +		SPECULAR_COLOR,
   65.20 +		ENVIRONMENT_INTENSITY,
   65.21 +		
   65.22  		END_RESERVED_UNIFORMS
   65.23  	} eGLSLReservedUniforms;
   65.24  
   65.25 @@ -176,7 +184,7 @@
   65.26  	void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE);
   65.27  	BOOL	linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);
   65.28  	BOOL	validateProgramObject(GLhandleARB obj);
   65.29 -	GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels = -1);
   65.30 +	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);
   65.31  
   65.32  	// Implemented in the application to actually point to the shader directory.
   65.33  	virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual
    66.1 --- a/indra/llrender/llvertexbuffer.cpp	Thu Jul 18 15:14:55 2013 -0400
    66.2 +++ b/indra/llrender/llvertexbuffer.cpp	Thu Jul 18 18:43:58 2013 -0400
    66.3 @@ -342,13 +342,32 @@
    66.4  	sizeof(LLVector2), // TYPE_TEXCOORD3,
    66.5  	sizeof(LLColor4U), // TYPE_COLOR,
    66.6  	sizeof(LLColor4U), // TYPE_EMISSIVE, only alpha is used currently
    66.7 -	sizeof(LLVector4), // TYPE_BINORMAL,
    66.8 +	sizeof(LLVector4), // TYPE_TANGENT,
    66.9  	sizeof(F32),	   // TYPE_WEIGHT,
   66.10  	sizeof(LLVector4), // TYPE_WEIGHT4,
   66.11  	sizeof(LLVector4), // TYPE_CLOTHWEIGHT,
   66.12  	sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes
   66.13  };
   66.14  
   66.15 +static std::string vb_type_name[] =
   66.16 +{
   66.17 +	"TYPE_VERTEX",
   66.18 +	"TYPE_NORMAL",
   66.19 +	"TYPE_TEXCOORD0",
   66.20 +	"TYPE_TEXCOORD1",
   66.21 +	"TYPE_TEXCOORD2",
   66.22 +	"TYPE_TEXCOORD3",
   66.23 +	"TYPE_COLOR",
   66.24 +	"TYPE_EMISSIVE",
   66.25 +	"TYPE_TANGENT",
   66.26 +	"TYPE_WEIGHT",
   66.27 +	"TYPE_WEIGHT4",
   66.28 +	"TYPE_CLOTHWEIGHT",
   66.29 +	"TYPE_TEXTURE_INDEX",
   66.30 +	"TYPE_MAX",
   66.31 +	"TYPE_INDEX",	
   66.32 +};
   66.33 +
   66.34  U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = 
   66.35  {
   66.36  	GL_TRIANGLES,
   66.37 @@ -523,16 +542,16 @@
   66.38  				}
   66.39  			}
   66.40  
   66.41 -			if (sLastMask & MAP_BINORMAL)
   66.42 +			if (sLastMask & MAP_TANGENT)
   66.43  			{
   66.44 -				if (!(data_mask & MAP_BINORMAL))
   66.45 +				if (!(data_mask & MAP_TANGENT))
   66.46  				{
   66.47  					glClientActiveTextureARB(GL_TEXTURE2_ARB);
   66.48  					glDisableClientState(GL_TEXTURE_COORD_ARRAY);
   66.49  					glClientActiveTextureARB(GL_TEXTURE0_ARB);
   66.50  				}
   66.51  			}
   66.52 -			else if (data_mask & MAP_BINORMAL)
   66.53 +			else if (data_mask & MAP_TANGENT)
   66.54  			{
   66.55  				glClientActiveTextureARB(GL_TEXTURE2_ARB);
   66.56  				glEnableClientState(GL_TEXTURE_COORD_ARRAY);
   66.57 @@ -593,8 +612,9 @@
   66.58  		glVertexPointer(3, GL_FLOAT, 0, pos[0].mV);
   66.59  		glNormalPointer(GL_FLOAT, 0, norm[0].mV);
   66.60  	}
   66.61 -
   66.62 +	LLGLSLShader::startProfile();
   66.63  	glDrawArrays(sGLMode[mode], 0, count);
   66.64 +	LLGLSLShader::stopProfile(count, mode);
   66.65  }
   66.66  
   66.67  //static
   66.68 @@ -631,7 +651,9 @@
   66.69  		glVertexPointer(3, GL_FLOAT, 16, pos);
   66.70  	}
   66.71  
   66.72 +	LLGLSLShader::startProfile();
   66.73  	glDrawElements(sGLMode[mode], num_indices, GL_UNSIGNED_SHORT, indicesp);
   66.74 +	LLGLSLShader::stopProfile(num_indices, mode);
   66.75  }
   66.76  
   66.77  void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const
   66.78 @@ -731,9 +753,14 @@
   66.79  	U16* idx = ((U16*) getIndicesPointer())+indices_offset;
   66.80  
   66.81  	stop_glerror();
   66.82 +	LLGLSLShader::startProfile();
   66.83  	glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, 
   66.84  		idx);
   66.85 +	LLGLSLShader::stopProfile(count, mode);
   66.86  	stop_glerror();
   66.87 +
   66.88 +	
   66.89 +
   66.90  	placeFence();
   66.91  }
   66.92  
   66.93 @@ -777,8 +804,10 @@
   66.94  	}
   66.95  
   66.96  	stop_glerror();
   66.97 +	LLGLSLShader::startProfile();
   66.98  	glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT,
   66.99  		((U16*) getIndicesPointer()) + indices_offset);
  66.100 +	LLGLSLShader::stopProfile(count, mode);
  66.101  	stop_glerror();
  66.102  	placeFence();
  66.103  }
  66.104 @@ -820,9 +849,12 @@
  66.105  
  66.106  	{
  66.107  		LLFastTimer t2(FTM_GL_DRAW_ARRAYS);
  66.108 -		stop_glerror();
  66.109 -		glDrawArrays(sGLMode[mode], first, count);
  66.110 -	}
  66.111 +	stop_glerror();
  66.112 +	LLGLSLShader::startProfile();
  66.113 +	glDrawArrays(sGLMode[mode], first, count);
  66.114 +	LLGLSLShader::stopProfile(count, mode);
  66.115 +        }
  66.116 +
  66.117  	stop_glerror();
  66.118  	placeFence();
  66.119  }
  66.120 @@ -1322,7 +1354,7 @@
  66.121  		2, //TYPE_TEXCOORD3,
  66.122  		4, //TYPE_COLOR,
  66.123  		4, //TYPE_EMISSIVE,
  66.124 -		3, //TYPE_BINORMAL,
  66.125 +		4, //TYPE_TANGENT,
  66.126  		1, //TYPE_WEIGHT,
  66.127  		4, //TYPE_WEIGHT4,
  66.128  		4, //TYPE_CLOTHWEIGHT,
  66.129 @@ -1339,7 +1371,7 @@
  66.130  		GL_FLOAT, //TYPE_TEXCOORD3,
  66.131  		GL_UNSIGNED_BYTE, //TYPE_COLOR,
  66.132  		GL_UNSIGNED_BYTE, //TYPE_EMISSIVE,
  66.133 -		GL_FLOAT,   //TYPE_BINORMAL,
  66.134 +		GL_FLOAT,   //TYPE_TANGENT,
  66.135  		GL_FLOAT, //TYPE_WEIGHT,
  66.136  		GL_FLOAT, //TYPE_WEIGHT4,
  66.137  		GL_FLOAT, //TYPE_CLOTHWEIGHT,
  66.138 @@ -1356,7 +1388,7 @@
  66.139  		false, //TYPE_TEXCOORD3,
  66.140  		false, //TYPE_COLOR,
  66.141  		false, //TYPE_EMISSIVE,
  66.142 -		false, //TYPE_BINORMAL,
  66.143 +		false, //TYPE_TANGENT,
  66.144  		false, //TYPE_WEIGHT,
  66.145  		false, //TYPE_WEIGHT4,
  66.146  		false, //TYPE_CLOTHWEIGHT,
  66.147 @@ -1373,7 +1405,7 @@
  66.148  		GL_FALSE, //TYPE_TEXCOORD3,
  66.149  		GL_TRUE, //TYPE_COLOR,
  66.150  		GL_TRUE, //TYPE_EMISSIVE,
  66.151 -		GL_FALSE,   //TYPE_BINORMAL,
  66.152 +		GL_FALSE,   //TYPE_TANGENT,
  66.153  		GL_FALSE, //TYPE_WEIGHT,
  66.154  		GL_FALSE, //TYPE_WEIGHT4,
  66.155  		GL_FALSE, //TYPE_CLOTHWEIGHT,
  66.156 @@ -2038,14 +2070,21 @@
  66.157  {
  66.158  	return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index, count, map_range);
  66.159  }
  66.160 -
  66.161 +bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index, S32 count, bool map_range)
  66.162 +{
  66.163 +	return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index, count, map_range);
  66.164 +}
  66.165  bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
  66.166  {
  66.167  	return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count, map_range);
  66.168  }
  66.169 -bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
  66.170 +bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
  66.171  {
  66.172 -	return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index, count, map_range);
  66.173 +	return VertexBufferStrider<LLVector3,TYPE_TANGENT>::get(*this, strider, index, count, map_range);
  66.174 +}
  66.175 +bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector4a>& strider, S32 index, S32 count, bool map_range)
  66.176 +{
  66.177 +	return VertexBufferStrider<LLVector4a,TYPE_TANGENT>::get(*this, strider, index, count, map_range);
  66.178  }
  66.179  bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index, S32 count, bool map_range)
  66.180  {
  66.181 @@ -2200,7 +2239,7 @@
  66.182  
  66.183  			if ((data_mask & required_mask) != required_mask)
  66.184  			{
  66.185 -				llerrs << "Shader consumption mismatches data provision." << llendl;
  66.186 +				llwarns << "Shader consumption mismatches data provision." << llendl;
  66.187  			}
  66.188  		}
  66.189  	}
  66.190 @@ -2318,6 +2357,14 @@
  66.191  
  66.192  	if (gDebugGL && ((data_mask & mTypeMask) != data_mask))
  66.193  	{
  66.194 +		for (U32 i = 0; i < LLVertexBuffer::TYPE_MAX; ++i)
  66.195 +		{
  66.196 +			U32 mask = 1 << i;
  66.197 +			if (mask & data_mask && !(mask & mTypeMask))
  66.198 +			{ //bit set in data_mask, but not set in mTypeMask
  66.199 +				llwarns << "Missing required component " << vb_type_name[i] << llendl;
  66.200 +			}
  66.201 +		}
  66.202  		llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;
  66.203  	}
  66.204  
  66.205 @@ -2347,11 +2394,11 @@
  66.206  			void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]);
  66.207  			glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);
  66.208  		}
  66.209 -		if (data_mask & MAP_BINORMAL)
  66.210 +		if (data_mask & MAP_TANGENT)
  66.211  		{
  66.212 -			S32 loc = TYPE_BINORMAL;
  66.213 -			void* ptr = (void*)(base + mOffsets[TYPE_BINORMAL]);
  66.214 -			glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], ptr);
  66.215 +			S32 loc = TYPE_TANGENT;
  66.216 +			void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]);
  66.217 +			glVertexAttribPointerARB(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);
  66.218  		}
  66.219  		if (data_mask & MAP_TEXCOORD0)
  66.220  		{
  66.221 @@ -2429,10 +2476,10 @@
  66.222  			glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
  66.223  			glClientActiveTextureARB(GL_TEXTURE0_ARB);
  66.224  		}
  66.225 -		if (data_mask & MAP_BINORMAL)
  66.226 +		if (data_mask & MAP_TANGENT)
  66.227  		{
  66.228  			glClientActiveTextureARB(GL_TEXTURE2_ARB);
  66.229 -			glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL]));
  66.230 +			glTexCoordPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT]));
  66.231  			glClientActiveTextureARB(GL_TEXTURE0_ARB);
  66.232  		}
  66.233  		if (data_mask & MAP_TEXCOORD0)
    67.1 --- a/indra/llrender/llvertexbuffer.h	Thu Jul 18 15:14:55 2013 -0400
    67.2 +++ b/indra/llrender/llvertexbuffer.h	Thu Jul 18 18:43:58 2013 -0400
    67.3 @@ -174,7 +174,7 @@
    67.4  		TYPE_TEXCOORD3,
    67.5  		TYPE_COLOR,
    67.6  		TYPE_EMISSIVE,
    67.7 -		TYPE_BINORMAL,
    67.8 +		TYPE_TANGENT,
    67.9  		TYPE_WEIGHT,
   67.10  		TYPE_WEIGHT4,
   67.11  		TYPE_CLOTHWEIGHT,
   67.12 @@ -192,7 +192,7 @@
   67.13  		MAP_COLOR = (1<<TYPE_COLOR),
   67.14  		MAP_EMISSIVE = (1<<TYPE_EMISSIVE),
   67.15  		// These use VertexAttribPointer and should possibly be made generic
   67.16 -		MAP_BINORMAL = (1<<TYPE_BINORMAL),
   67.17 +		MAP_TANGENT = (1<<TYPE_TANGENT),
   67.18  		MAP_WEIGHT = (1<<TYPE_WEIGHT),
   67.19  		MAP_WEIGHT4 = (1<<TYPE_WEIGHT4),
   67.20  		MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT),
   67.21 @@ -250,8 +250,10 @@
   67.22  	bool getIndexStrider(LLStrider<U16>& strider, S32 index=0, S32 count = -1, bool map_range = false);
   67.23  	bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
   67.24  	bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
   67.25 +	bool getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
   67.26  	bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
   67.27 -	bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
   67.28 +	bool getTangentStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
   67.29 +	bool getTangentStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false);
   67.30  	bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
   67.31  	bool getTextureIndexStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
   67.32  	bool getEmissiveStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
    68.1 --- a/indra/llui/lllocalcliprect.cpp	Thu Jul 18 15:14:55 2013 -0400
    68.2 +++ b/indra/llui/lllocalcliprect.cpp	Thu Jul 18 18:43:58 2013 -0400
    68.3 @@ -33,7 +33,7 @@
    68.4  
    68.5  
    68.6  LLScreenClipRect::LLScreenClipRect(const LLRect& rect, BOOL enabled)
    68.7 -	:	mScissorState(GL_SCISSOR_TEST),
    68.8 +:	mScissorState(GL_SCISSOR_TEST),
    68.9  	mEnabled(enabled)
   68.10  {
   68.11  	if (mEnabled)
   68.12 @@ -100,10 +100,10 @@
   68.13  // LLLocalClipRect
   68.14  //---------------------------------------------------------------------------
   68.15  LLLocalClipRect::LLLocalClipRect(const LLRect& rect, BOOL enabled /* = TRUE */)
   68.16 -	:	LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX, 
   68.17 -	rect.mTop + LLFontGL::sCurOrigin.mY, 
   68.18 -	rect.mRight + LLFontGL::sCurOrigin.mX, 
   68.19 -	rect.mBottom + LLFontGL::sCurOrigin.mY), enabled)
   68.20 +:	LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX, 
   68.21 +					rect.mTop + LLFontGL::sCurOrigin.mY, 
   68.22 +					rect.mRight + LLFontGL::sCurOrigin.mX, 
   68.23 +					rect.mBottom + LLFontGL::sCurOrigin.mY), enabled)
   68.24  {}
   68.25  
   68.26  LLLocalClipRect::~LLLocalClipRect()
    69.1 --- a/indra/llui/llxuiparser.cpp	Thu Jul 18 15:14:55 2013 -0400
    69.2 +++ b/indra/llui/llxuiparser.cpp	Thu Jul 18 18:43:58 2013 -0400
    69.3 @@ -1309,10 +1309,8 @@
    69.4  void LLXUIParser::parserWarning(const std::string& message)
    69.5  {
    69.6  #ifdef LL_WINDOWS
    69.7 -	// use Visual Studo friendly formatting of output message for easy access to originating xml
    69.8 -	llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()).c_str());
    69.9 -	utf16str += '\n';
   69.10 -	OutputDebugString(utf16str.c_str());
   69.11 +	// use Visual Studio friendly formatting of output message for easy access to originating xml
   69.12 +	LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()));
   69.13  #else
   69.14  	Parser::parserWarning(message);
   69.15  #endif
   69.16 @@ -1321,9 +1319,8 @@
   69.17  void LLXUIParser::parserError(const std::string& message)
   69.18  {
   69.19  #ifdef LL_WINDOWS
   69.20 -	llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()).c_str());
   69.21 -	utf16str += '\n';
   69.22 -	OutputDebugString(utf16str.c_str());
   69.23 +        // use Visual Studio friendly formatting of output message for easy access to originating xml
   69.24 +	LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()));
   69.25  #else
   69.26  	Parser::parserError(message);
   69.27  #endif
   69.28 @@ -1640,10 +1637,8 @@
   69.29  void LLSimpleXUIParser::parserWarning(const std::string& message)
   69.30  {
   69.31  #ifdef LL_WINDOWS
   69.32 -	// use Visual Studo friendly formatting of output message for easy access to originating xml
   69.33 -	llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()).c_str());
   69.34 -	utf16str += '\n';
   69.35 -	OutputDebugString(utf16str.c_str());
   69.36 +	// use Visual Studio friendly formatting of output message for easy access to originating xml
   69.37 +	LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()));
   69.38  #else
   69.39  	Parser::parserWarning(message);
   69.40  #endif
   69.41 @@ -1652,9 +1647,8 @@
   69.42  void LLSimpleXUIParser::parserError(const std::string& message)
   69.43  {
   69.44  #ifdef LL_WINDOWS
   69.45 -	llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()).c_str());
   69.46 -	utf16str += '\n';
   69.47 -	OutputDebugString(utf16str.c_str());
   69.48 +        // use Visual Studio friendly formatting of output message for easy access to originating xml
   69.49 +	LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()));
   69.50  #else
   69.51  	Parser::parserError(message);
   69.52  #endif
    70.1 --- a/indra/llvfs/lldir_win32.cpp	Thu Jul 18 15:14:55 2013 -0400
    70.2 +++ b/indra/llvfs/lldir_win32.cpp	Thu Jul 18 18:43:58 2013 -0400
    70.3 @@ -131,7 +131,7 @@
    70.4  		mAppRODataDir = mExecutableDir;
    70.5  	}
    70.6  
    70.7 -	llinfos << "mAppRODataDir = " << mAppRODataDir << llendl;
    70.8 +//	llinfos << "mAppRODataDir = " << mAppRODataDir << llendl;
    70.9  
   70.10  	mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
   70.11  
    71.1 --- a/indra/llvfs/llvfile.cpp	Thu Jul 18 15:14:55 2013 -0400
    71.2 +++ b/indra/llvfs/llvfile.cpp	Thu Jul 18 18:43:58 2013 -0400
    71.3 @@ -135,7 +135,7 @@
    71.4  		data = NULL;
    71.5  	}
    71.6  	else
    71.7 -	{		
    71.8 +	{
    71.9  		data = (U8*) ll_aligned_malloc_16(file_size);
   71.10  		file.read(data, file_size);	/* Flawfinder: ignore */ 
   71.11  		
    72.1 --- a/indra/llwindow/CMakeLists.txt	Thu Jul 18 15:14:55 2013 -0400
    72.2 +++ b/indra/llwindow/CMakeLists.txt	Thu Jul 18 18:43:58 2013 -0400
    72.3 @@ -165,7 +165,7 @@
    72.4    set(llwindowheadless_HEADER_FILES
    72.5         llwindowmesaheadless.h
    72.6         llmousehandler.h
    72.7 -       )
    72.8 +    )
    72.9    add_library (llwindowheadless
   72.10      ${llwindow_SOURCE_FILES}
   72.11      ${llwindowheadless_SOURCE_FILES}
   72.12 @@ -180,12 +180,12 @@
   72.13    list(APPEND llwindow_SOURCE_FILES ${llwindow_HEADER_FILES})
   72.14  endif (llwindow_HEADER_FILES)
   72.15  
   72.16 -list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES})
   72.17 +  list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES})
   72.18  
   72.19 -add_library (llwindow
   72.20 -  ${llwindow_SOURCE_FILES}
   72.21 -  ${viewer_SOURCE_FILES}
   72.22 -  )
   72.23 +  add_library (llwindow
   72.24 +    ${llwindow_SOURCE_FILES}
   72.25 +    ${viewer_SOURCE_FILES}
   72.26 +    )
   72.27  
   72.28  if (SDL_FOUND)
   72.29    set_property(TARGET llwindow
   72.30 @@ -193,5 +193,5 @@
   72.31      )
   72.32  endif (SDL_FOUND)
   72.33  
   72.34 -target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES})
   72.35 +  target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES})
   72.36  
    73.1 --- a/indra/llxml/CMakeLists.txt	Thu Jul 18 15:14:55 2013 -0400
    73.2 +++ b/indra/llxml/CMakeLists.txt	Thu Jul 18 18:43:58 2013 -0400
    73.3 @@ -42,7 +42,7 @@
    73.4  add_library (llxml ${llxml_SOURCE_FILES})
    73.5  # Libraries on which this library depends, needed for Linux builds
    73.6  # Sort by high-level to low-level
    73.7 -target_link_libraries(llxml
    73.8 +target_link_libraries( llxml
    73.9      ${LLVFS_LIBRARIES}
   73.10      ${LLMATH_LIBRARIES}
   73.11      ${LLCOMMON_LIBRARIES}
    74.1 --- a/indra/lscript/lscript_compile/indra.l	Thu Jul 18 15:14:55 2013 -0400
    74.2 +++ b/indra/lscript/lscript_compile/indra.l	Thu Jul 18 18:43:58 2013 -0400
    74.3 @@ -79,11 +79,9 @@
    74.4  #define yyfree indra_free
    74.5  
    74.6  
    74.7 -#if defined(__cplusplus)
    74.8 -extern "C" { int yylex( void ); }
    74.9 -extern "C" { int yyparse( void ); }
   74.10 -extern "C" { int yyerror(const char *fmt, ...); }
   74.11 -#endif
   74.12 +int yylex( void );
   74.13 +int yyparse( void );
   74.14 +int yyerror(const char *fmt, ...);
   74.15  
   74.16  %}
   74.17  
    75.1 --- a/indra/lscript/lscript_compile/indra.y	Thu Jul 18 15:14:55 2013 -0400
    75.2 +++ b/indra/lscript/lscript_compile/indra.y	Thu Jul 18 18:43:58 2013 -0400
    75.3 @@ -2,10 +2,6 @@
    75.4  	#include "linden_common.h"
    75.5  	#include "lscript_tree.h"
    75.6  
    75.7 -    #ifdef __cplusplus
    75.8 -    extern "C" {
    75.9 -    #endif
   75.10 -
   75.11  	int yylex(void);
   75.12  	int yyparse( void );
   75.13  	int yyerror(const char *fmt, ...);
   75.14 @@ -20,9 +16,6 @@
   75.15  	#pragma warning( disable : 4065 )	// warning: switch statement contains 'default' but no 'case' labels
   75.16  	#endif
   75.17  
   75.18 -    #ifdef __cplusplus
   75.19 -    }
   75.20 -    #endif
   75.21  %}
   75.22  
   75.23  %union
    76.1 Binary file indra/mac_crash_logger/CrashReporter.nib has changed
    77.1 --- a/indra/media_plugins/winmmshim/winmm_shim.cpp	Thu Jul 18 15:14:55 2013 -0400
    77.2 +++ b/indra/media_plugins/winmmshim/winmm_shim.cpp	Thu Jul 18 18:43:58 2013 -0400
    77.3 @@ -56,7 +56,7 @@
    77.4  		// grab winmm.dll from system path, where it should live
    77.5  		wsprintf(dll_path, "%s\\winmm.dll", system_path);
    77.6  		HMODULE winmm_handle = ::LoadLibrary(dll_path);
    77.7 -		
    77.8 +
    77.9  		if (winmm_handle != NULL)
   77.10  		{	// we have a dll, let's get out pointers!
   77.11  			initialized = true;
    78.1 --- a/indra/newview/CMakeLists.txt	Thu Jul 18 15:14:55 2013 -0400
    78.2 +++ b/indra/newview/CMakeLists.txt	Thu Jul 18 18:43:58 2013 -0400
    78.3 @@ -4,6 +4,7 @@
    78.4  
    78.5  include(00-Common)
    78.6  include(Boost)
    78.7 +include(BuildVersion)
    78.8  include(DBusGlib)
    78.9  include(DirectX)
   78.10  include(OpenSSL)
   78.11 @@ -173,6 +174,7 @@
   78.12      lldrawpoolavatar.cpp
   78.13      lldrawpoolbump.cpp
   78.14      lldrawpoolground.cpp
   78.15 +    lldrawpoolmaterials.cpp
   78.16      lldrawpoolsimple.cpp
   78.17      lldrawpoolsky.cpp
   78.18      lldrawpoolterrain.cpp
   78.19 @@ -357,6 +359,7 @@
   78.20      llmaniptranslate.cpp
   78.21      llmarketplacefunctions.cpp
   78.22      llmarketplacenotifications.cpp
   78.23 +    llmaterialmgr.cpp
   78.24      llmediactrl.cpp
   78.25      llmediadataclient.cpp
   78.26      llmenuoptionpathfindingrebakenavmesh.cpp
   78.27 @@ -753,6 +756,7 @@
   78.28      lldrawpoolalpha.h
   78.29      lldrawpoolavatar.h
   78.30      lldrawpoolbump.h
   78.31 +    lldrawpoolmaterials.h
   78.32      lldrawpoolground.h
   78.33      lldrawpoolsimple.h
   78.34      lldrawpoolsky.h
   78.35 @@ -937,6 +941,7 @@
   78.36      llmaniptranslate.h
   78.37      llmarketplacefunctions.h
   78.38      llmarketplacenotifications.h
   78.39 +    llmaterialmgr.h
   78.40      llmediactrl.h
   78.41      llmediadataclient.h
   78.42      llmenuoptionpathfindingrebakenavmesh.h
   78.43 @@ -1563,7 +1568,7 @@
   78.44  
   78.45  if (OPENAL)
   78.46    set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_OPENAL")
   78.47 -endif (OPENAL)          
   78.48 +endif (OPENAL)
   78.49  
   78.50  if (FMODEX)
   78.51    set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX")
   78.52 @@ -1983,7 +1988,7 @@
   78.53    configure_file(
   78.54       "${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"
   78.55       "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app/Contents/Info.plist"
   78.56 -               )
   78.57 +    )
   78.58  
   78.59    add_custom_command(
   78.60      TARGET ${VIEWER_BINARY_NAME} POST_BUILD
   78.61 @@ -2137,6 +2142,40 @@
   78.62    )
   78.63  
   78.64    set_source_files_properties(
   78.65 +    llviewerhelputil.cpp
   78.66 +    PROPERTIES
   78.67 +    LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
   78.68 +  )
   78.69 +
   78.70 +  set_source_files_properties(
   78.71 +    llremoteparcelrequest.cpp
   78.72 +    PROPERTIES
   78.73 +    LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
   78.74 +  )
   78.75 +
   78.76 +  set_source_files_properties(
   78.77 +    llworldmap.cpp
   78.78 +    llworldmipmap.cpp
   78.79 +    PROPERTIES
   78.80 +    LL_TEST_ADDITIONAL_SOURCE_FILES 
   78.81 +    tests/llviewertexture_stub.cpp
   78.82 +    #llviewertexturelist.cpp
   78.83 +    LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
   78.84 +  )
   78.85 +
   78.86 +  set_source_files_properties(
   78.87 +    llmediadataclient.cpp
   78.88 +    PROPERTIES
   78.89 +    LL_TEST_ADDITIONAL_LIBRARIES "${LLPRIMITIVE_LIBRARIES}"
   78.90 +  )
   78.91 +
   78.92 +  set_source_files_properties(
   78.93 +    llagentaccess.cpp
   78.94 +    PROPERTIES
   78.95 +    LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
   78.96 +  )
   78.97 +
   78.98 +  set_source_files_properties(
   78.99      lllogininstance.cpp
  78.100      PROPERTIES
  78.101      LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
    79.1 --- a/indra/newview/VIEWER_VERSION.txt	Thu Jul 18 15:14:55 2013 -0400
    79.2 +++ b/indra/newview/VIEWER_VERSION.txt	Thu Jul 18 18:43:58 2013 -0400
    79.3 @@ -1,1 +1,1 @@
    79.4 -3.5.4
    79.5 +3.6.2
    80.1 --- a/indra/newview/app_settings/settings.xml	Thu Jul 18 15:14:55 2013 -0400
    80.2 +++ b/indra/newview/app_settings/settings.xml	Thu Jul 18 18:43:58 2013 -0400
    80.3 @@ -2873,6 +2873,17 @@
    80.4        <key>Value</key>
    80.5        <integer>0</integer>
    80.6      </map>
    80.7 +  <key>DefaultBlankNormalTexture</key>
    80.8 +  <map>
    80.9 +    <key>Comment</key>
   80.10 +    <string>Texture used as 'Blank' in texture picker for normal maps. (UUID texture reference)</string>
   80.11 +    <key>Persist</key>
   80.12 +    <integer>1</integer>
   80.13 +    <key>Type</key>
   80.14 +    <string>String</string>
   80.15 +    <key>Value</key>
   80.16 +    <string>5b53359e-59dd-d8a2-04c3-9e65134da47a</string>
   80.17 +  </map>
   80.18  	<key>DefaultFemaleAvatar</key>
   80.19  	<map>
   80.20  	  <key>Comment</key>
   80.21 @@ -2895,8 +2906,29 @@
   80.22  	  <key>Value</key>
   80.23  	  <string>Male Shape &amp; Outfit</string>
   80.24  	</map>
   80.25 -
   80.26 -    <key>DefaultObjectTexture</key>
   80.27 +  <key>DefaultObjectNormalTexture</key>
   80.28 +  <map>
   80.29 +    <key>Comment</key>
   80.30 +    <string>Texture used as 'Default' in texture picker for normal map. (UUID texture reference)</string>
   80.31 +    <key>Persist</key>
   80.32 +    <integer>1</integer>
   80.33 +    <key>Type</key>
   80.34 +    <string>String</string>
   80.35 +    <key>Value</key>
   80.36 +    <string>85f28839-7a1c-b4e3-d71d-967792970a7b</string>
   80.37 +  </map>
   80.38 +  <key>DefaultObjectSpecularTexture</key>
   80.39 +  <map>
   80.40 +    <key>Comment</key>
   80.41 +    <string>Texture used as 'Default' in texture picker for specular map. (UUID texture reference)</string>
   80.42 +    <key>Persist</key>
   80.43 +    <integer>1</integer>
   80.44 +    <key>Type</key>
   80.45 +    <string>String</string>
   80.46 +    <key>Value</key>
   80.47 +    <string>87e0e8f7-8729-1ea8-cfc9-8915773009db</string>
   80.48 +  </map>
   80.49 +  <key>DefaultObjectTexture</key>
   80.50      <map>
   80.51        <key>Comment</key>
   80.52        <string>Texture used as 'Default' in texture picker. (UUID texture reference)</string>
   80.53 @@ -3347,17 +3379,6 @@
   80.54        <key>Value</key>
   80.55        <integer>1</integer>
   80.56      </map>
   80.57 -    <key>EnableTextureAtlas</key>
   80.58 -    <map>
   80.59 -      <key>Comment</key>
   80.60 -      <string>Whether to use texture atlas or not</string>
   80.61 -      <key>Persist</key>
   80.62 -      <integer>1</integer>
   80.63 -      <key>Type</key>
   80.64 -      <string>Boolean</string>
   80.65 -      <key>Value</key>
   80.66 -      <integer>0</integer>
   80.67 -    </map>
   80.68      <key>EnableUIHints</key>
   80.69      <map>
   80.70        <key>Comment</key>
   80.71 @@ -7711,7 +7732,7 @@
   80.72      <key>Type</key>
   80.73      <string>S32</string>
   80.74      <key>Value</key>
   80.75 -    <integer>4</integer>
   80.76 +    <integer>3</integer>
   80.77    </map>
   80.78  
   80.79    <key>OctreeAlphaDistanceFactor</key>
   80.80 @@ -8440,7 +8461,7 @@
   80.81    <key>RenderSpotLightsInNondeferred</key>
   80.82    <map>
   80.83      <key>Comment</key>
   80.84 -    <string>Whether to support projectors as spotlights when Lighting and Shadows is disabled</string>
   80.85 +    <string>Whether to support projectors as spotlights when Advanced Lighting Model is disabled</string>
   80.86      <key>Persist</key>
   80.87      <integer>1</integer>
   80.88      <key>Type</key>
   80.89 @@ -8483,7 +8504,6 @@
   80.90      <key>Value</key>
   80.91      <real>1.0</real>
   80.92    </map>
   80.93 -
   80.94    <key>RenderDeferredTreeShadowBias</key>
   80.95    <map>
   80.96      <key>Comment</key>
   80.97 @@ -8581,7 +8601,7 @@
   80.98      <key>Type</key>
   80.99      <string>U32</string>
  80.100      <key>Value</key>
  80.101 -    <real>512</real>
  80.102 +    <real>1024</real>
  80.103    </map>
  80.104  
  80.105    <key>RenderSpecularResY</key>
  80.106 @@ -8593,7 +8613,7 @@
  80.107      <key>Type</key>
  80.108      <string>U32</string>
  80.109      <key>Value</key>
  80.110 -    <real>128</real>
  80.111 +    <real>256</real>
  80.112    </map>
  80.113  
  80.114    <key>RenderSpecularExponent</key>
  80.115 @@ -8611,7 +8631,7 @@
  80.116    <key>RenderDeferred</key>
  80.117    <map>
  80.118      <key>Comment</key>
  80.119 -    <string>Use deferred rendering pipeline.</string>
  80.120 +    <string>Use deferred rendering pipeline (Advanced Lighting Model).</string>
  80.121      <key>Persist</key>
  80.122      <integer>1</integer>
  80.123      <key>Type</key>
  80.124 @@ -8799,7 +8819,7 @@
  80.125      <key>RenderAutoMaskAlphaNonDeferred</key>
  80.126      <map>
  80.127        <key>Comment</key>
  80.128 -      <string>Use alpha masks where appropriate, in the non-deferred (non-'Lighting and Shadows') graphics mode</string>
  80.129 +      <string>Use alpha masks where appropriate when not using the Advanced Lighting Model</string>
  80.130        <key>Persist</key>
  80.131        <integer>1</integer>
  80.132        <key>Type</key>
  80.133 @@ -8810,7 +8830,7 @@
  80.134      <key>RenderAutoMaskAlphaDeferred</key>
  80.135      <map>
  80.136        <key>Comment</key>
  80.137 -      <string>Use alpha masks where appropriate, in the deferred ('Lighting and Shadows') graphics mode</string>
  80.138 +      <string>Use alpha masks where appropriate in the Advanced Lighting Model</string>
  80.139        <key>Persist</key>
  80.140        <integer>1</integer>
  80.141        <key>Type</key>
  80.142 @@ -12461,390 +12481,379 @@
  80.143        <key>Value</key>
  80.144        <integer>3</integer>
  80.145      </map>
  80.146 +    <key>UpdaterServiceCheckPeriod</key>
  80.147 +    <map>
  80.148 +      <key>Comment</key>
  80.149 +      <string>Default period between update checking.</string>
  80.150 +      <key>Persist</key>
  80.151 +      <integer>1</integer>
  80.152 +      <key>Type</key>
  80.153 +      <string>U32</string>
  80.154 +      <key>Value</key>
  80.155 +      <integer>3600</integer>
  80.156 +    </map>
  80.157 +    <key>UpdaterServiceURL</key>
  80.158 +    <map>
  80.159 +      <key>Comment</key>
  80.160 +      <string>Default location for the updater service.</string>
  80.161 +      <key>Persist</key>
  80.162 +      <integer>0</integer>
  80.163 +      <key>Type</key>
  80.164 +      <string>String</string>
  80.165 +      <key>Value</key>
  80.166 +      <string>https://update.secondlife.com</string>
  80.167 +    </map>
  80.168 +    <key>UpdaterServicePath</key>
  80.169 +    <map>
  80.170 +      <key>Comment</key>
  80.171 +      <string>Path on the update server host.</string>
  80.172 +      <key>Persist</key>
  80.173 +      <integer>0</integer>
  80.174 +      <key>Type</key>
  80.175 +      <string>String</string>
  80.176 +      <key>Value</key>
  80.177 +      <string>update</string>
  80.178 +    </map>
  80.179      <key>UpdaterWillingToTest</key>
  80.180      <map>
  80.181        <key>Comment</key>
  80.182 -      <string>Allow upgrades to release candidate viewers with new features and fixes.</string>
  80.183 -      <key>Persist</key>
  80.184 -      <integer>1</integer>
  80.185 -      <key>Type</key>
  80.186 -      <string>Boolean</string>
  80.187 -      <key>Value</key>
  80.188 -      <integer>1</integer>
  80.189 -    </map>
  80.190 -    <key>UpdaterServiceCheckPeriod</key>
  80.191 -    <map>
  80.192 -      <key>Comment</key>
  80.193 -      <string>Default period between update checking.</string>
  80.194 +      <string>Whether or not the updater should offer test candidate upgrades.</string>
  80.195 +      <key>Persist</key>
  80.196 +      <integer>1</integer>
  80.197 +      <key>Type</key>
  80.198 +      <string>Boolean</string>
  80.199 +      <key>Value</key>
  80.200 +      <string>1</string>
  80.201 +    </map>
  80.202 +    <key>UploadBakedTexOld</key>
  80.203 +    <map>
  80.204 +      <key>Comment</key>
  80.205 +      <string>Forces the baked texture pipeline to upload using the old method.</string>
  80.206 +      <key>Persist</key>
  80.207 +      <integer>1</integer>
  80.208 +      <key>Type</key>
  80.209 +      <string>Boolean</string>
  80.210 +      <key>Value</key>
  80.211 +      <integer>0</integer>
  80.212 +    </map>
  80.213 +    <key>UseAltKeyForMenus</key>
  80.214 +    <map>
  80.215 +      <key>Comment</key>
  80.216 +      <string>Access menus via keyboard by tapping Alt</string>
  80.217 +      <key>Persist</key>
  80.218 +      <integer>1</integer>
  80.219 +      <key>Type</key>
  80.220 +      <string>Boolean</string>
  80.221 +      <key>Value</key>
  80.222 +      <integer>0</integer>
  80.223 +    </map>
  80.224 +    <key>UseChatBubbles</key>
  80.225 +    <map>
  80.226 +      <key>Comment</key>
  80.227 +      <string>Show chat above avatars head in chat bubbles</string>
  80.228 +      <key>Persist</key>
  80.229 +      <integer>1</integer>
  80.230 +      <key>Type</key>
  80.231 +      <string>Boolean</string>
  80.232 +      <key>Value</key>
  80.233 +      <integer>0</integer>
  80.234 +    </map>
  80.235 +    <key>UseCircuitCodeMaxRetries</key>
  80.236 +    <map>
  80.237 +      <key>Comment</key>
  80.238 +      <string>Max timeout count for the initial UseCircuitCode message</string>
  80.239 +      <key>Persist</key>
  80.240 +      <integer>0</integer>
  80.241 +      <key>Type</key>
  80.242 +      <string>S32</string>
  80.243 +      <key>Value</key>
  80.244 +      <real>3</real>
  80.245 +    </map>
  80.246 +    <key>UseCircuitCodeTimeout</key>
  80.247 +    <map>
  80.248 +      <key>Comment</key>
  80.249 +      <string>Timeout duration in seconds for the initial UseCircuitCode message</string>
  80.250 +      <key>Persist</key>
  80.251 +      <integer>0</integer>
  80.252 +      <key>Type</key>
  80.253 +      <string>F32</string>
  80.254 +      <key>Value</key>
  80.255 +      <real>5.0</real>
  80.256 +    </map>
  80.257 +    <key>UseDebugLogin</key>
  80.258 +    <map>
  80.259 +      <key>Comment</key>
  80.260 +      <string>Provides extra control over which grid to connect to</string>
  80.261 +      <key>Persist</key>
  80.262 +      <integer>1</integer>
  80.263 +      <key>Type</key>
  80.264 +      <string>Boolean</string>
  80.265 +      <key>Value</key>
  80.266 +      <integer>0</integer>
  80.267 +    </map>
  80.268 +    <key>UseDebugMenus</key>
  80.269 +    <map>
  80.270 +      <key>Comment</key>
  80.271 +      <string>Turns on "Debug" menu</string>
  80.272 +      <key>Persist</key>
  80.273 +      <integer>1</integer>
  80.274 +      <key>Type</key>
  80.275 +      <string>Boolean</string>
  80.276 +      <key>Value</key>
  80.277 +      <integer>0</integer>
  80.278 +    </map>
  80.279 +    <key>UseDefaultColorPicker</key>
  80.280 +    <map>
  80.281 +      <key>Comment</key>
  80.282 +      <string>Use color picker supplied by operating system</string>
  80.283 +      <key>Persist</key>
  80.284 +      <integer>1</integer>
  80.285 +      <key>Type</key>
  80.286 +      <string>Boolean</string>
  80.287 +      <key>Value</key>
  80.288 +      <integer>0</integer>
  80.289 +    </map>
  80.290 +  <key>UseDisplayNames</key>
  80.291 +  <map>
  80.292 +    <key>Comment</key>
  80.293 +    <string>Use new, changeable, unicode names</string>
  80.294 +    <key>Persist</key>
  80.295 +    <integer>1</integer>
  80.296 +    <key>Type</key>
  80.297 +    <string>Boolean</string>
  80.298 +    <key>Value</key>
  80.299 +    <integer>1</integer>
  80.300 +  </map>
  80.301 +    <key>UseEnergy</key>
  80.302 +    <map>
  80.303 +      <key>Comment</key>
  80.304 +      <string />
  80.305 +      <key>Persist</key>
  80.306 +      <integer>0</integer>
  80.307 +      <key>Type</key>
  80.308 +      <string>Boolean</string>
  80.309 +      <key>Value</key>
  80.310 +      <integer>1</integer>
  80.311 +    </map>
  80.312 +    <key>UseEnvironmentFromRegion</key>
  80.313 +    <map>
  80.314 +      <key>Comment</key>
  80.315 +      <string>Choose whether to use the region's environment settings, or override them with the local settings.</string>
  80.316 +      <key>Persist</key>
  80.317 +      <integer>1</integer>
  80.318 +      <key>Type</key>
  80.319 +      <string>Boolean</string>
  80.320 +      <key>Value</key>
  80.321 +      <integer>1</integer>
  80.322 +    </map>
  80.323 +    <key>UseDayCycle</key>
  80.324 +    <map>
  80.325 +      <key>Comment</key>
  80.326 +      <string>Whether to use use a day cycle or a fixed sky.</string>
  80.327 +      <key>Persist</key>
  80.328 +      <integer>1</integer>
  80.329 +      <key>Type</key>
  80.330 +      <string>Boolean</string>
  80.331 +      <key>Value</key>
  80.332 +      <integer>1</integer>
  80.333 +    </map>
  80.334 +    <key>WaterPresetName</key>
  80.335 +    <map>
  80.336 +      <key>Comment</key>
  80.337 +      <string>Water preset to use. May be superseded by region settings.</string>
  80.338 +      <key>Persist</key>
  80.339 +      <integer>1</integer>
  80.340 +      <key>Type</key>
  80.341 +      <string>String</string>
  80.342 +      <key>Value</key>
  80.343 +      <string>Default</string>
  80.344 +    </map>
  80.345 +    <key>SkyPresetName</key>
  80.346 +    <map>
  80.347 +      <key>Comment</key>
  80.348 +      <string>Sky preset to use. May be superseded by region settings or by a day cycle (see DayCycleName).</string>
  80.349 +      <key>Persist</key>
  80.350 +      <integer>1</integer>
  80.351 +      <key>Type</key>
  80.352 +      <string>String</string>
  80.353 +      <key>Value</key>
  80.354 +      <string>Default</string>
  80.355 +    </map>
  80.356 +    <key>DayCycleName</key>
  80.357 +    <map>
  80.358 +      <key>Comment</key>
  80.359 +      <string>Day cycle to use. May be superseded by region settings.</string>
  80.360 +      <key>Persist</key>
  80.361 +      <integer>1</integer>
  80.362 +      <key>Type</key>
  80.363 +      <string>String</string>
  80.364 +      <key>Value</key>
  80.365 +      <string>Default</string>
  80.366 +    </map>
  80.367 +    <key>UseExternalBrowser</key>
  80.368 +    <map>
  80.369 +      <key>Comment</key>
  80.370 +      <string>Use default browser when opening web pages instead of in-world browser.</string>
  80.371 +      <key>Persist</key>
  80.372 +      <integer>1</integer>
  80.373 +      <key>Type</key>
  80.374 +      <string>Boolean</string>
  80.375 +      <key>Value</key>
  80.376 +      <boolean>1</boolean>
  80.377 +    </map>
  80.378 +    <key>UseFreezeFrame</key>
  80.379 +    <map>
  80.380 +      <key>Comment</key>
  80.381 +      <string>Freeze time when taking snapshots.</string>
  80.382 +      <key>Persist</key>
  80.383 +      <integer>1</integer>
  80.384 +      <key>Type</key>
  80.385 +      <string>Boolean</string>
  80.386 +      <key>Value</key>
  80.387 +      <integer>0</integer>
  80.388 +    </map>
  80.389 +    <key>UseOcclusion</key>
  80.390 +    <map>
  80.391 +      <key>Comment</key>
  80.392 +      <string>Enable object culling based on occlusion (coverage) by other objects</string>
  80.393 +      <key>Persist</key>
  80.394 +      <integer>1</integer>
  80.395 +      <key>Type</key>
  80.396 +      <string>Boolean</string>
  80.397 +      <key>Value</key>
  80.398 +      <integer>1</integer>
  80.399 +    </map>
  80.400 +  <key>RenderSynchronousOcclusion</key>
  80.401 +  <map>
  80.402 +    <key>Comment</key>
  80.403 +    <string>Don't let occlusion queries get more than one frame behind (block until they complete).</string>
  80.404 +    <key>Persist</key>
  80.405 +    <integer>1</integer>
  80.406 +    <key>Type</key>
  80.407 +    <string>Boolean</string>
  80.408 +    <key>Value</key>
  80.409 +    <integer>1</integer>
  80.410 +  </map>
  80.411 +    <key>RenderDelayVBUpdate</key>
  80.412 +    <map>
  80.413 +      <key>Comment</key>
  80.414 +      <string>Delay vertex buffer updates until just before rendering</string>
  80.415 +      <key>Persist</key>
  80.416 +      <integer>1</integer>
  80.417 +      <key>Type</key>
  80.418 +      <string>Boolean</string>
  80.419 +      <key>Value</key>
  80.420 +      <integer>0</integer>
  80.421 +    </map>
  80.422 +    <key>sourceid</key>
  80.423 +    <map>
  80.424 +      <key>Comment</key>
  80.425 +      <string>Identify referring agency to Linden web servers</string>
  80.426 +      <key>Persist</key>
  80.427 +      <integer>1</integer>
  80.428 +      <key>Type</key>
  80.429 +      <string>String</string>
  80.430 +      <key>Value</key>
  80.431 +      <string />
  80.432 +    </map>
  80.433 +    <key>SpeakerParticipantRemoveDelay</key>
  80.434 +    <map>
  80.435 +      <key>Comment</key>
  80.436 +      <string>Timeout to remove participants who is not in channel before removed from list of active speakers (text/voice chat)</string>
  80.437 +      <key>Persist</key>
  80.438 +      <integer>1</integer>
  80.439 +      <key>Type</key>
  80.440 +      <string>F32</string>
  80.441 +      <key>Value</key>
  80.442 +      <real>10.0</real>
  80.443 +    </map>
  80.444 +    <key>SpellCheck</key>
  80.445 +    <map>
  80.446 +      <key>Comment</key>
  80.447 +      <string>Enable spellchecking on line and text editors</string>
  80.448 +      <key>Persist</key>
  80.449 +      <integer>1</integer>
  80.450 +      <key>Type</key>
  80.451 +      <string>Boolean</string>
  80.452 +      <key>Value</key>
  80.453 +      <integer>1</integer>
  80.454 +    </map>
  80.455 +    <key>SpellCheckDictionary</key>
  80.456 +    <map>
  80.457 +      <key>Comment</key>
  80.458 +      <string>Current primary and secondary dictionaries used for spell checking</string>
  80.459 +      <key>Persist</key>
  80.460 +      <integer>1</integer>
  80.461 +      <key>Type</key>
  80.462 +      <string>String</string>
  80.463 +      <key>Value</key>
  80.464 +      <string>English (United States),Second Life Glossary</string>
  80.465 +    </map>
  80.466 +    <key>UseNewWalkRun</key>
  80.467 +    <map>
  80.468 +      <key>Comment</key>
  80.469 +      <string>Replace standard walk/run animations with new ones.</string>
  80.470 +      <key>Persist</key>
  80.471 +      <integer>1</integer>
  80.472 +      <key>Type</key>
  80.473 +      <string>Boolean</string>
  80.474 +      <key>Value</key>
  80.475 +      <integer>1</integer>
  80.476 +    </map>
  80.477 +  <key>UsePeopleAPI</key>
  80.478 +  <map>
  80.479 +    <key>Comment</key>
  80.480 +    <string>Use the people API cap for avatar name fetching, use old legacy protocol if false. Requires restart.</string>
  80.481 +    <key>Persist</key>
  80.482 +    <integer>1</integer>
  80.483 +    <key>Type</key>
  80.484 +    <string>Boolean</string>
  80.485 +    <key>Value</key>
  80.486 +    <integer>1</integer>
  80.487 +  </map>
  80.488 +    <key>UseStartScreen</key>
  80.489 +    <map>
  80.490 +      <key>Comment</key>
  80.491 +      <string>Whether to load a start screen image or not.</string>
  80.492 +      <key>Persist</key>
  80.493 +      <integer>1</integer>
  80.494 +      <key>Type</key>
  80.495 +      <string>Boolean</string>
  80.496 +      <key>Value</key>
  80.497 +      <integer>1</integer>
  80.498 +    </map>
  80.499 +    <key>UseWebPagesOnPrims</key>
  80.500 +    <map>
  80.501 +      <key>Comment</key>
  80.502 +      <string>[NOT USED]</string>
  80.503 +      <key>Persist</key>
  80.504 +      <integer>1</integer>
  80.505 +      <key>Type</key>
  80.506 +      <string>Boolean</string>
  80.507 +      <key>Value</key>
  80.508 +      <integer>0</integer>
  80.509 +    </map>
  80.510 +    <key>UserConnectionPort</key>
  80.511 +    <map>
  80.512 +      <key>Comment</key>
  80.513 +      <string>Port that this client transmits on.</string>
  80.514        <key>Persist</key>
  80.515        <integer>1</integer>
  80.516        <key>Type</key>
  80.517        <string>U32</string>
  80.518        <key>Value</key>
  80.519 -      <integer>3600</integer>
  80.520 -    </map>
  80.521 -    <key>UpdaterServiceURL</key>
  80.522 -    <map>
  80.523 -      <key>Comment</key>
  80.524 -      <string>Default location for the updater service.</string>
  80.525 -      <key>Persist</key>
  80.526 -      <integer>0</integer>
  80.527 -      <key>Type</key>
  80.528 -      <string>String</string>
  80.529 -      <key>Value</key>
  80.530 -      <string>https://update.secondlife.com</string>
  80.531 -    </map>
  80.532 -    <key>UpdaterServicePath</key>
  80.533 -    <map>
  80.534 -      <key>Comment</key>
  80.535 -      <string>Path on the update server host.</string>
  80.536 -      <key>Persist</key>
  80.537 -      <integer>0</integer>
  80.538 -      <key>Type</key>
  80.539 -      <string>String</string>
  80.540 -      <key>Value</key>
  80.541 -      <string>update</string>
  80.542 -    </map>
  80.543 -    <key>UpdaterWillingToTest</key>
  80.544 -    <map>
  80.545 -      <key>Comment</key>
  80.546 -      <string>Whether or not the updater should offer test candidate upgrades.</string>
  80.547 -      <key>Persist</key>
  80.548 -      <integer>1</integer>
  80.549 -      <key>Type</key>
  80.550 -      <string>Boolean</string>
  80.551 -      <key>Value</key>
  80.552 -      <string>1</string>
  80.553 -    </map>
  80.554 -    <key>UploadBakedTexOld</key>
  80.555 -    <map>
  80.556 -      <key>Comment</key>
  80.557 -      <string>Forces the baked texture pipeline to upload using the old method.</string>
  80.558 -      <key>Persist</key>
  80.559 -      <integer>1</integer>
  80.560 -      <key>Type</key>
  80.561 -      <string>Boolean</string>
  80.562 -      <key>Value</key>
  80.563 -      <integer>0</integer>
  80.564 -    </map>
  80.565 -    <key>UseAltKeyForMenus</key>
  80.566 -    <map>
  80.567 -      <key>Comment</key>
  80.568 -      <string>Access menus via keyboard by tapping Alt</string>
  80.569 -      <key>Persist</key>
  80.570 -      <integer>1</integer>
  80.571 -      <key>Type</key>
  80.572 -      <string>Boolean</string>
  80.573 -      <key>Value</key>
  80.574 -      <integer>0</integer>
  80.575 -    </map>
  80.576 -    <key>UseChatBubbles</key>
  80.577 -    <map>
  80.578 -      <key>Comment</key>
  80.579 -      <string>Show chat above avatars head in chat bubbles</string>
  80.580 -      <key>Persist</key>
  80.581 -      <integer>1</integer>
  80.582 -      <key>Type</key>
  80.583 -      <string>Boolean</string>
  80.584 -      <key>Value</key>
  80.585 -      <integer>0</integer>
  80.586 -    </map>
  80.587 -    <key>UseCircuitCodeMaxRetries</key>
  80.588 -    <map>
  80.589 -      <key>Comment</key>
  80.590 -      <string>Max timeout count for the initial UseCircuitCode message</string>
  80.591 -      <key>Persist</key>
  80.592 -      <integer>0</integer>
  80.593 -      <key>Type</key>
  80.594 -      <string>S32</string>
  80.595 -      <key>Value</key>
  80.596 -      <real>3</real>
  80.597 -    </map>
  80.598 -    <key>UseCircuitCodeTimeout</key>
  80.599 -    <map>
  80.600 -      <key>Comment</key>
  80.601 -      <string>Timeout duration in seconds for the initial UseCircuitCode message</string>
  80.602 -      <key>Persist</key>
  80.603 -      <integer>0</integer>
  80.604 -      <key>Type</key>
  80.605 -      <string>F32</string>
  80.606 -      <key>Value</key>
  80.607 -      <real>5.0</real>
  80.608 -    </map>
  80.609 -    <key>UseDebugLogin</key>
  80.610 -    <map>
  80.611 -      <key>Comment</key>
  80.612 -      <string>Provides extra control over which grid to connect to</string>
  80.613 -      <key>Persist</key>
  80.614 -      <integer>1</integer>
  80.615 -      <key>Type</key>
  80.616 -      <string>Boolean</string>
  80.617 -      <key>Value</key>
  80.618 -      <integer>0</integer>
  80.619 -    </map>
  80.620 -    <key>UseDebugMenus</key>
  80.621 -    <map>
  80.622 -      <key>Comment</key>
  80.623 -      <string>Turns on "Debug" menu</string>
  80.624 -      <key>Persist</key>
  80.625 -      <integer>1</integer>
  80.626 -      <key>Type</key>
  80.627 -      <string>Boolean</string>
  80.628 -      <key>Value</key>
  80.629 -      <integer>0</integer>
  80.630 -    </map>
  80.631 -    <key>UseDefaultColorPicker</key>
  80.632 -    <map>
  80.633 -      <key>Comment</key>
  80.634 -      <string>Use color picker supplied by operating system</string>
  80.635 -      <key>Persist</key>
  80.636 -      <integer>1</integer>
  80.637 -      <key>Type</key>
  80.638 -      <string>Boolean</string>
  80.639 -      <key>Value</key>
  80.640 -      <integer>0</integer>
  80.641 -    </map>
  80.642 -  <key>UseDisplayNames</key>
  80.643 -  <map>
  80.644 -    <key>Comment</key>
  80.645 -    <string>Use new, changeable, unicode names</string>
  80.646 -    <key>Persist</key>
  80.647 -    <integer>1</integer>
  80.648 -    <key>Type</key>
  80.649 -    <string>Boolean</string>
  80.650 -    <key>Value</key>
  80.651 -    <integer>1</integer>
  80.652 -  </map>
  80.653 -    <key>UseEnergy</key>
  80.654 -    <map>
  80.655 -      <key>Comment</key>
  80.656 +      <integer>0</integer>
  80.657 +    </map>
  80.658 +    <key>UserLogFile</key>
  80.659 +    <map>
  80.660 +      <key>Comment</key>
  80.661 +      <string>User specified log file name.</string>
  80.662 +      <key>Persist</key>
  80.663 +      <integer>1</integer>
  80.664 +      <key>Type</key>
  80.665 +      <string>String</string>
  80.666 +      <key>Value</key>
  80.667        <string />
  80.668 -      <key>Persist</key>
  80.669 -      <integer>0</integer>
  80.670 -      <key>Type</key>
  80.671 -      <string>Boolean</string>
  80.672 -      <key>Value</key>
  80.673 -      <integer>1</integer>
  80.674 -    </map>
  80.675 -    <key>UseEnvironmentFromRegion</key>
  80.676 -    <map>
  80.677 -      <key>Comment</key>
  80.678 -      <string>Choose whether to use the region's environment settings, or override them with the local settings.</string>
  80.679 -      <key>Persist</key>
  80.680 -      <integer>1</integer>
  80.681 -      <key>Type</key>
  80.682 -      <string>Boolean</string>
  80.683 -      <key>Value</key>
  80.684 -      <integer>1</integer>
  80.685 -    </map>
  80.686 -    <key>UseDayCycle</key>
  80.687 -    <map>
  80.688 -      <key>Comment</key>
  80.689 -      <string>Whether to use use a day cycle or a fixed sky.</string>
  80.690 -      <key>Persist</key>
  80.691 -      <integer>1</integer>
  80.692 -      <key>Type</key>
  80.693 -      <string>Boolean</string>
  80.694 -      <key>Value</key>
  80.695 -      <integer>1</integer>
  80.696 -    </map>
  80.697 -    <key>WaterPresetName</key>
  80.698 -    <map>
  80.699 -      <key>Comment</key>
  80.700 -      <string>Water preset to use. May be superseded by region settings.</string>
  80.701 -      <key>Persist</key>
  80.702 -      <integer>1</integer>
  80.703 -      <key>Type</key>
  80.704 -      <string>String</string>
  80.705 -      <key>Value</key>
  80.706 -      <string>Default</string>
  80.707 -    </map>
  80.708 -    <key>SkyPresetName</key>
  80.709 -    <map>
  80.710 -      <key>Comment</key>
  80.711 -      <string>Sky preset to use. May be superseded by region settings or by a day cycle (see DayCycleName).</string>
  80.712 -      <key>Persist</key>
  80.713 -      <integer>1</integer>
  80.714 -      <key>Type</key>
  80.715 -      <string>String</string>
  80.716 -      <key>Value</key>
  80.717 -      <string>Default</string>
  80.718 -    </map>
  80.719 -    <key>DayCycleName</key>
  80.720 -    <map>
  80.721 -      <key>Comment</key>
  80.722 -      <string>Day cycle to use. May be superseded by region settings.</string>
  80.723 -      <key>Persist</key>
  80.724 -      <integer>1</integer>
  80.725 -      <key>Type</key>
  80.726 -      <string>String</string>
  80.727 -      <key>Value</key>
  80.728 -      <string>Default</string>
  80.729 -    </map>
  80.730 -    <key>UseExternalBrowser</key>
  80.731 -    <map>
  80.732 -      <key>Comment</key>
  80.733 -      <string>Use default browser when opening web pages instead of in-world browser.</string>
  80.734 -      <key>Persist</key>
  80.735 -      <integer>1</integer>
  80.736 -      <key>Type</key>
  80.737 -      <string>Boolean</string>
  80.738 -      <key>Value</key>
  80.739 -      <boolean>1</boolean>
  80.740 -    </map>
  80.741 -    <key>UseFreezeFrame</key>
  80.742 -    <map>
  80.743 -      <key>Comment</key>
  80.744 -      <string>Freeze time when taking snapshots.</string>
  80.745 -      <key>Persist</key>
  80.746 -      <integer>1</integer>
  80.747 -      <key>Type</key>
  80.748 -      <string>Boolean</string>
  80.749 -      <key>Value</key>
  80.750 -      <integer>0</integer>
  80.751 -    </map>
  80.752 -    <key>UseOcclusion</key>
  80.753 -    <map>
  80.754 -      <key>Comment</key>
  80.755 -      <string>Enable object culling based on occlusion (coverage) by other objects</string>
  80.756 -      <key>Persist</key>
  80.757 -      <integer>1</integer>
  80.758 -      <key>Type</key>
  80.759 -      <string>Boolean</string>
  80.760 -      <key>Value</key>
  80.761 -      <integer>1</integer>
  80.762 -    </map>
  80.763 -  <key>RenderSynchronousOcclusion</key>
  80.764 -  <map>
  80.765 -    <key>Comment</key>
  80.766 -    <string>Don't let occlusion queries get more than one frame behind (block until they complete).</string>
  80.767 -    <key>Persist</key>
  80.768 -    <integer>1</integer>
  80.769 -    <key>Type</key>
  80.770 -    <string>Boolean</string>
  80.771 -    <key>Value</key>
  80.772 -    <integer>1</integer>
  80.773 -  </map>
  80.774 -    <key>RenderDelayVBUpdate</key>
  80.775 -    <map>
  80.776 -      <key>Comment</key>
  80.777 -      <string>Delay vertex buffer updates until just before rendering</string>
  80.778 -      <key>Persist</key>
  80.779 -      <integer>1</integer>
  80.780 -      <key>Type</key>
  80.781 -      <string>Boolean</string>
  80.782 -      <key>Value</key>
  80.783 -      <integer>0</integer>
  80.784 -    </map>
  80.785 -    <key>sourceid</key>
  80.786 -    <map>
  80.787 -      <key>Comment</key>
  80.788 -      <string>Identify referring agency to Linden web servers</string>
  80.789 -      <key>Persist</key>
  80.790 -      <integer>1</integer>
  80.791 -      <key>Type</key>
  80.792 -      <string>String</string>
  80.793 -      <key>Value</key>
  80.794 -      <string />
  80.795 -    </map>
  80.796 -    <key>SpeakerParticipantRemoveDelay</key>
  80.797 -    <map>
  80.798 -      <key>Comment</key>
  80.799 -      <string>Timeout to remove participants who is not in channel before removed from list of active speakers (text/voice chat)</string>
  80.800 -      <key>Persist</key>
  80.801 -      <integer>1</integer>
  80.802 -      <key>Type</key>
  80.803 -      <string>F32</string>
  80.804 -      <key>Value</key>
  80.805 -      <real>10.0</real>
  80.806 -    </map>
  80.807 -    <key>SpellCheck</key>
  80.808 -    <map>
  80.809 -      <key>Comment</key>
  80.810 -      <string>Enable spellchecking on line and text editors</string>
  80.811 -      <key>Persist</key>
  80.812 -      <integer>1</integer>
  80.813 -      <key>Type</key>
  80.814 -      <string>Boolean</string>
  80.815 -      <key>Value</key>
  80.816 -      <integer>1</integer>
  80.817 -    </map>
  80.818 -    <key>SpellCheckDictionary</key>
  80.819 -    <map>
  80.820 -      <key>Comment</key>
  80.821 -      <string>Current primary and secondary dictionaries used for spell checking</string>
  80.822 -      <key>Persist</key>
  80.823 -      <integer>1</integer>
  80.824 -      <key>Type</key>
  80.825 -      <string>String</string>
  80.826 -      <key>Value</key>
  80.827 -      <string>English (United States),Second Life Glossary</string>
  80.828 -    </map>
  80.829 -    <key>UseNewWalkRun</key>
  80.830 -    <map>
  80.831 -      <key>Comment</key>
  80.832 -      <string>Replace standard walk/run animations with new ones.</string>
  80.833 -      <key>Persist</key>
  80.834 -      <integer>1</integer>
  80.835 -      <key>Type</key>
  80.836 -      <string>Boolean</string>
  80.837 -      <key>Value</key>
  80.838 -      <integer>1</integer>
  80.839 -    </map>
  80.840 -  <key>UsePeopleAPI</key>
  80.841 -  <map>
  80.842 -    <key>Comment</key>
  80.843 -    <string>Use the people API cap for avatar name fetching, use old legacy protocol if false. Requires restart.</string>
  80.844 -    <key>Persist</key>
  80.845 -    <integer>1</integer>
  80.846 -    <key>Type</key>
  80.847 -    <string>Boolean</string>
  80.848 -    <key>Value</key>
  80.849 -    <integer>1</integer>
  80.850 -  </map>
  80.851 -    <key>UseStartScreen</key>
  80.852 -    <map>
  80.853 -      <key>Comment</key>
  80.854 -      <string>Whether to load a start screen image or not.</string>
  80.855 -      <key>Persist</key>
  80.856 -      <integer>1</integer>
  80.857 -      <key>Type</key>
  80.858 -      <string>Boolean</string>
  80.859 -      <key>Value</key>
  80.860 -      <integer>1</integer>
  80.861 -    </map>
  80.862 -    <key>UseWebPagesOnPrims</key>
  80.863 -    <map>
  80.864 -      <key>Comment</key>
  80.865 -      <string>[NOT USED]</string>
  80.866 -      <key>Persist</key>
  80.867 -      <integer>1</integer>
  80.868 -      <key>Type</key>
  80.869 -      <string>Boolean</string>
  80.870 -      <key>Value</key>
  80.871 -      <integer>0</integer>
  80.872 -    </map>
  80.873 -    <key>UserConnectionPort</key>
  80.874 -    <map>
  80.875 -      <key>Comment</key>
  80.876 -      <string>Port that this client transmits on.</string>
  80.877 -      <key>Persist</key>
  80.878 -      <integer>1</integer>
  80.879 -      <key>Type</key>
  80.880 -      <string>U32</string>
  80.881 -      <key>Value</key>
  80.882 -      <integer>0</integer>
  80.883 -    </map>
  80.884 -    <key>UserLogFile</key>
  80.885 -    <map>
  80.886 -      <key>Comment</key>
  80.887 -      <string>User specified log file name.</string>
  80.888 -      <key>Persist</key>
  80.889 -      <integer>1</integer>
  80.890 -      <key>Type</key>
  80.891 -      <string>String</string>
  80.892 -      <key>Value</key>
  80.893 -      <string />
  80.894      </map>
  80.895      <key>UserLoginInfo</key>
  80.896      <map>
  80.897 @@ -12855,7 +12864,6 @@
  80.898        <key>Type</key>
  80.899        <string>LLSD</string>
  80.900        <key>Value</key>
  80.901 -      <string/>
  80.902      </map>
  80.903      <key>VFSOldSize</key>
  80.904      <map>
  80.905 @@ -14524,5 +14532,16 @@
  80.906      <key>Value</key>
  80.907      <integer>7000</integer>
  80.908    </map>
  80.909 +  <key>DisablePrecacheDelayAfterTeleporting</key>
  80.910 +  <map>
  80.911 +    <key>Comment</key>
  80.912 +    <string>Disables the artificial delay in the viewer that precaches some incoming assets</string>
  80.913 +    <key>Persist</key>
  80.914 +    <integer>0</integer>
  80.915 +    <key>Type</key>
  80.916 +    <string>Boolean</string>
  80.917 +    <key>Value</key>
  80.918 +    <integer>0</integer>
  80.919 +  </map>
  80.920  </map>
  80.921  </llsd>
    81.1 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl	Thu Jul 18 15:14:55 2013 -0400
    81.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl	Thu Jul 18 18:43:58 2013 -0400
    81.3 @@ -25,17 +25,33 @@
    81.4   
    81.5  #extension GL_ARB_texture_rectangle : enable
    81.6  
    81.7 +#define INDEXED 1
    81.8 +#define NON_INDEXED 2
    81.9 +#define NON_INDEXED_NO_COLOR 3
   81.10 +
   81.11  #ifdef DEFINE_GL_FRAGCOLOR
   81.12  out vec4 frag_color;
   81.13  #else
   81.14  #define frag_color gl_FragColor
   81.15  #endif
   81.16  
   81.17 -uniform sampler2DRect depthMap;
   81.18 +#if HAS_SHADOW
   81.19 +uniform sampler2DShadow shadowMap0;
   81.20 +uniform sampler2DShadow shadowMap1;
   81.21 +uniform sampler2DShadow shadowMap2;
   81.22 +uniform sampler2DShadow shadowMap3;
   81.23  
   81.24 -vec4 diffuseLookup(vec2 texcoord);
   81.25 +uniform vec2 shadow_res;
   81.26  
   81.27 -uniform vec2 screen_res;
   81.28 +uniform mat4 shadow_matrix[6];
   81.29 +uniform vec4 shadow_clip;
   81.30 +uniform float shadow_bias;
   81.31 +
   81.32 +#endif
   81.33 +
   81.34 +#ifdef USE_DIFFUSE_TEX
   81.35 +uniform sampler2D diffuseMap;
   81.36 +#endif
   81.37  
   81.38  vec3 atmosLighting(vec3 light);
   81.39  vec3 scaleSoftClip(vec3 light);
   81.40 @@ -45,11 +61,80 @@
   81.41  VARYING vec3 vary_fragcoord;
   81.42  VARYING vec3 vary_position;
   81.43  VARYING vec3 vary_pointlight_col;
   81.44 +VARYING vec2 vary_texcoord0;
   81.45 +VARYING vec3 vary_norm;
   81.46  
   81.47 +#ifdef USE_VERTEX_COLOR
   81.48  VARYING vec4 vertex_color;
   81.49 -VARYING vec2 vary_texcoord0;
   81.50 +#endif
   81.51  
   81.52 -uniform mat4 inv_proj;
   81.53 +uniform vec4 light_position[8];
   81.54 +uniform vec3 light_direction[8];
   81.55 +uniform vec3 light_attenuation[8]; 
   81.56 +uniform vec3 light_diffuse[8];
   81.57 +
   81.58 +uniform vec2 screen_res;
   81.59 +
   81.60 +vec3 calcDirectionalLight(vec3 n, vec3 l)
   81.61 +{
   81.62 +	float a = max(dot(n,l),0.0);
   81.63 +	a = pow(a, 1.0/1.3);
   81.64 +	return vec3(a,a,a);
   81.65 +}
   81.66 +
   81.67 +vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
   81.68 +{
   81.69 +	//get light vector
   81.70 +	vec3 lv = lp.xyz-v;
   81.71 +	
   81.72 +	//get distance
   81.73 +	float d = length(lv);
   81.74 +	
   81.75 +	float da = 0.0;
   81.76 +
   81.77 +	if (d > 0.0 && la > 0.0 && fa > 0.0)
   81.78 +	{
   81.79 +		//normalize light vector
   81.80 +		lv = normalize(lv);
   81.81 +	
   81.82 +		//distance attenuation
   81.83 +		float dist = d/la;
   81.84 +		da = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
   81.85 +		da *= da;
   81.86 +		da *= 1.4;
   81.87 +	
   81.88 +
   81.89 +		// spotlight coefficient.
   81.90 +		float spot = max(dot(-ln, lv), is_pointlight);
   81.91 +		da *= spot*spot; // GL_SPOT_EXPONENT=2
   81.92 +
   81.93 +		//angular attenuation
   81.94 +		da *= max(dot(n, lv), 0.0);		
   81.95 +	}
   81.96 +
   81.97 +	return vec3(da,da,da);	
   81.98 +}
   81.99 +
  81.100 +#if HAS_SHADOW
  81.101 +float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
  81.102 +{
  81.103 +	stc.xyz /= stc.w;
  81.104 +	stc.z += shadow_bias;
  81.105 +		
  81.106 +	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
  81.107 +	
  81.108 +	float cs = shadow2D(shadowMap, stc.xyz).x;
  81.109 +	float shadow = cs;
  81.110 +	
  81.111 +    shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
  81.112 +    shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
  81.113 +    shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
  81.114 +    shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
  81.115 +                       
  81.116 +    return shadow*0.2;
  81.117 +}
  81.118 +#endif
  81.119 +
  81.120  
  81.121  void main() 
  81.122  {
  81.123 @@ -58,16 +143,123 @@
  81.124  	
  81.125  	vec4 pos = vec4(vary_position, 1.0);
  81.126  	
  81.127 -	vec4 diff= diffuseLookup(vary_texcoord0.xy);
  81.128  
  81.129 -	vec4 col = vec4(vary_ambient + vary_directional.rgb, vertex_color.a);
  81.130 -	vec4 color = diff * col;
  81.131 +#if HAS_SHADOW
  81.132 +	float shadow = 0.0;
  81.133 +	vec4 spos = pos;
  81.134 +		
  81.135 +	if (spos.z > -shadow_clip.w)
  81.136 +	{	
  81.137 +		vec4 lpos;
  81.138 +		
  81.139 +		vec4 near_split = shadow_clip*-0.75;
  81.140 +		vec4 far_split = shadow_clip*-1.25;
  81.141 +		vec4 transition_domain = near_split-far_split;
  81.142 +		float weight = 0.0;
  81.143 +
  81.144 +		if (spos.z < near_split.z)
  81.145 +		{
  81.146 +			lpos = shadow_matrix[3]*spos;
  81.147 +			
  81.148 +			float w = 1.0;
  81.149 +			w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
  81.150 +			shadow += pcfShadow(shadowMap3, lpos)*w;
  81.151 +			weight += w;
  81.152 +			shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
  81.153 +		}
  81.154 +
  81.155 +		if (spos.z < near_split.y && spos.z > far_split.z)
  81.156 +		{
  81.157 +			lpos = shadow_matrix[2]*spos;
  81.158 +			
  81.159 +			float w = 1.0;
  81.160 +			w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
  81.161 +			w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
  81.162 +			shadow += pcfShadow(shadowMap2, lpos)*w;
  81.163 +			weight += w;
  81.164 +		}
  81.165 +
  81.166 +		if (spos.z < near_split.x && spos.z > far_split.y)
  81.167 +		{
  81.168 +			lpos = shadow_matrix[1]*spos;
  81.169 +			
  81.170 +			float w = 1.0;
  81.171 +			w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
  81.172 +			w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
  81.173 +			shadow += pcfShadow(shadowMap1, lpos)*w;
  81.174 +			weight += w;
  81.175 +		}
  81.176 +
  81.177 +		if (spos.z > far_split.x)
  81.178 +		{
  81.179 +			lpos = shadow_matrix[0]*spos;
  81.180 +							
  81.181 +			float w = 1.0;
  81.182 +			w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
  81.183 +				
  81.184 +			shadow += pcfShadow(shadowMap0, lpos)*w;
  81.185 +			weight += w;
  81.186 +		}
  81.187 +		
  81.188 +
  81.189 +		shadow /= weight;
  81.190 +	}
  81.191 +	else
  81.192 +	{
  81.193 +		shadow = 1.0;
  81.194 +	}
  81.195 +#endif
  81.196 +
  81.197 +#ifdef USE_INDEXED_TEX
  81.198 +	vec4 diff = diffuseLookup(vary_texcoord0.xy);
  81.199 +#else
  81.200 +	vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
  81.201 +#endif
  81.202 +	vec4 gamma_diff = diff;
  81.203 +
  81.204 +	diff.rgb = pow(diff.rgb, vec3(2.2f, 2.2f, 2.2f));
  81.205 +
  81.206 +#ifdef USE_VERTEX_COLOR
  81.207 +	float vertex_color_alpha = vertex_color.a;	
  81.208 +#else
  81.209 +	float vertex_color_alpha = 1.0;
  81.210 +#endif
  81.211 +	
  81.212 +	vec3 normal = vary_norm; 
  81.213 +	
  81.214 +	vec3 l = light_position[0].xyz;
  81.215 +	vec3 dlight = calcDirectionalLight(normal, l);
  81.216 +	dlight = dlight * vary_directional.rgb * vary_pointlight_col;
  81.217 +
  81.218 +#if HAS_SHADOW
  81.219 +	vec4 col = vec4(vary_ambient + dlight * shadow, vertex_color_alpha);
  81.220 +#else
  81.221 +	vec4 col = vec4(vary_ambient + dlight, vertex_color_alpha);
  81.222 +#endif
  81.223 +
  81.224 +	vec4 color = gamma_diff * col;
  81.225  	
  81.226  	color.rgb = atmosLighting(color.rgb);
  81.227  
  81.228  	color.rgb = scaleSoftClip(color.rgb);
  81.229  
  81.230 -	color.rgb += diff.rgb * vary_pointlight_col.rgb;
  81.231 +	color.rgb = pow(color.rgb, vec3(2.2));
  81.232 +	col = vec4(0,0,0,0);
  81.233 +
  81.234 +	
  81.235 +   #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);
  81.236 +
  81.237 +	LIGHT_LOOP(1)
  81.238 +	LIGHT_LOOP(2)
  81.239 +	LIGHT_LOOP(3)
  81.240 +	LIGHT_LOOP(4)
  81.241 +	LIGHT_LOOP(5)
  81.242 +	LIGHT_LOOP(6)
  81.243 +	LIGHT_LOOP(7)
  81.244 +
  81.245 +	color.rgb += diff.rgb * pow(vary_pointlight_col, vec3(2.2)) * col.rgb;
  81.246 +
  81.247 +	color.rgb = pow(color.rgb, vec3(1.0/2.2));
  81.248  
  81.249  	frag_color = color;
  81.250  }
    82.1 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl	Thu Jul 18 15:14:55 2013 -0400
    82.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl	Thu Jul 18 18:43:58 2013 -0400
    82.3 @@ -47,9 +47,51 @@
    82.4  VARYING vec3 vary_pointlight_col;
    82.5  VARYING vec2 vary_texcoord0;
    82.6  VARYING vec4 vertex_color;
    82.7 +VARYING vec3 vary_norm;
    82.8  
    82.9  uniform mat4 inv_proj;
   82.10  
   82.11 +uniform vec4 light_position[8];
   82.12 +uniform vec3 light_direction[8];
   82.13 +uniform vec3 light_attenuation[8]; 
   82.14 +uniform vec3 light_diffuse[8];
   82.15 +
   82.16 +vec3 calcDirectionalLight(vec3 n, vec3 l)
   82.17 +{
   82.18 +        float a = pow(max(dot(n,l),0.0), 0.7);
   82.19 +        return vec3(a,a,a);
   82.20 +}
   82.21 +
   82.22 +vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
   82.23 +{
   82.24 +	//get light vector
   82.25 +	vec3 lv = lp.xyz-v;
   82.26 +	
   82.27 +	//get distance
   82.28 +	float d = dot(lv,lv);
   82.29 +	
   82.30 +	float da = 0.0;
   82.31 +
   82.32 +	if (d > 0.0 && la > 0.0 && fa > 0.0)
   82.33 +	{
   82.34 +		//normalize light vector
   82.35 +		lv = normalize(lv);
   82.36 +	
   82.37 +		//distance attenuation
   82.38 +		float dist2 = d/la;
   82.39 +		da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
   82.40 +
   82.41 +		// spotlight coefficient.
   82.42 +		float spot = max(dot(-ln, lv), is_pointlight);
   82.43 +		da *= spot*spot; // GL_SPOT_EXPONENT=2
   82.44 +
   82.45 +		//angular attenuation
   82.46 +		da *= max(pow(dot(n, lv), 0.7), 0.0);		
   82.47 +	}
   82.48 +
   82.49 +	return vec3(da,da,da);	
   82.50 +}
   82.51 +
   82.52  vec4 getPosition(vec2 pos_screen)
   82.53  {
   82.54  	float depth = texture2DRect(depthMap, pos_screen.xy).a;
   82.55 @@ -72,14 +114,33 @@
   82.56  	
   82.57  	vec4 diff= texture2D(diffuseMap,vary_texcoord0.xy);
   82.58  
   82.59 -	vec4 col = vec4(vary_ambient + vary_directional.rgb, vertex_color.a);
   82.60 +	vec3 n = vary_norm;
   82.61 +	vec3 l = light_position[0].xyz;
   82.62 +	vec3 dlight = calcDirectionalLight(n, l);
   82.63 +	dlight = dlight * vary_directional.rgb * vary_pointlight_col;
   82.64 +
   82.65 +	vec4 col = vec4(vary_ambient + dlight, vertex_color.a);
   82.66  	vec4 color = diff * col;
   82.67  	
   82.68  	color.rgb = atmosLighting(color.rgb);
   82.69  
   82.70  	color.rgb = scaleSoftClip(color.rgb);
   82.71 +	vec3 light_col = vec3(0,0,0);
   82.72  
   82.73 -	color.rgb += diff.rgb * vary_pointlight_col.rgb;
   82.74 +  #define LIGHT_LOOP(i) \
   82.75 +	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);
   82.76 +
   82.77 +	LIGHT_LOOP(1)
   82.78 +	LIGHT_LOOP(2)
   82.79 +	LIGHT_LOOP(3)
   82.80 +	LIGHT_LOOP(4)
   82.81 +	LIGHT_LOOP(5)
   82.82 +	LIGHT_LOOP(6)
   82.83 +	LIGHT_LOOP(7)
   82.84 +
   82.85 +	color.rgb += diff.rgb * vary_pointlight_col * light_col;
   82.86 +
   82.87 +	color.rgb = pow(color.rgb, vec3(1.0/2.2));
   82.88  
   82.89  	frag_color = color;
   82.90  	//frag_color = vec4(1,0,1,1);
    83.1 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl	Thu Jul 18 15:14:55 2013 -0400
    83.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl	Thu Jul 18 18:43:58 2013 -0400
    83.3 @@ -46,6 +46,7 @@
    83.4  VARYING vec4 vertex_color;
    83.5  VARYING vec2 vary_texcoord0;
    83.6  
    83.7 +VARYING vec3 vary_norm;
    83.8  
    83.9  uniform float near_clip;
   83.10  
   83.11 @@ -104,7 +105,7 @@
   83.12  	
   83.13  	norm = position.xyz + normal.xyz;
   83.14  	norm = normalize(( trans*vec4(norm, 1.0) ).xyz-pos.xyz);
   83.15 -	
   83.16 +	vary_norm = norm;
   83.17  	vec4 frag_pos = projection_matrix * pos;
   83.18  	gl_Position = frag_pos;
   83.19  	
   83.20 @@ -112,27 +113,18 @@
   83.21  		
   83.22  	calcAtmospherics(pos.xyz);
   83.23  
   83.24 +	//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
   83.25  	vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
   83.26 -
   83.27 -	// Collect normal lights
   83.28 -	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);
   83.29 -	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);
   83.30 -	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);
   83.31 -	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);
   83.32 -	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);
   83.33 -	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);
   83.34 -
   83.35 -	vary_pointlight_col = col.rgb*diffuse_color.rgb;
   83.36 -
   83.37 +	vary_pointlight_col = diffuse_color.rgb;
   83.38  	col.rgb = vec3(0,0,0);
   83.39  
   83.40  	// Add windlight lights
   83.41  	col.rgb = atmosAmbient(vec3(0.));
   83.42  	
   83.43  	vary_ambient = col.rgb*diffuse_color.rgb;
   83.44 -	vary_directional = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
   83.45 +	vary_directional.rgb = atmosAffectDirectionalLight(1);
   83.46  	
   83.47 -	col.rgb = min(col.rgb*diffuse_color.rgb, 1.0);
   83.48 +	col.rgb = col.rgb*diffuse_color.rgb;
   83.49  	
   83.50  	vertex_color = col;
   83.51  
    84.1 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl	Thu Jul 18 15:14:55 2013 -0400
    84.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl	Thu Jul 18 18:43:58 2013 -0400
    84.3 @@ -23,22 +23,41 @@
    84.4   * $/LicenseInfo$
    84.5   */
    84.6  
    84.7 +#define INDEXED 1
    84.8 +#define NON_INDEXED 2
    84.9 +#define NON_INDEXED_NO_COLOR 3
   84.10 +
   84.11  uniform mat3 normal_matrix;
   84.12  uniform mat4 texture_matrix0;
   84.13 +uniform mat4 projection_matrix;
   84.14  uniform mat4 modelview_matrix;
   84.15  uniform mat4 modelview_projection_matrix;
   84.16  
   84.17  ATTRIBUTE vec3 position;
   84.18 +
   84.19 +#ifdef USE_INDEXED_TEX
   84.20  void passTextureIndex();
   84.21 +#endif
   84.22 +
   84.23  ATTRIBUTE vec3 normal;
   84.24 +
   84.25 +#ifdef USE_VERTEX_COLOR
   84.26  ATTRIBUTE vec4 diffuse_color;
   84.27 +#endif
   84.28 +
   84.29  ATTRIBUTE vec2 texcoord0;
   84.30  
   84.31 +#ifdef HAS_SKIN
   84.32 +mat4 getObjectSkinnedTransform();
   84.33 +#else
   84.34 +#ifdef IS_AVATAR_SKIN
   84.35 +mat4 getSkinnedTransform();
   84.36 +#endif
   84.37 +#endif
   84.38 +
   84.39  vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
   84.40  void calcAtmospherics(vec3 inPositionEye);
   84.41  
   84.42 -float calcDirectionalLight(vec3 n, vec3 l);
   84.43 -
   84.44  vec3 atmosAmbient(vec3 light);
   84.45  vec3 atmosAffectDirectionalLight(float lightIntensity);
   84.46  vec3 scaleDownLight(vec3 light);
   84.47 @@ -50,26 +69,24 @@
   84.48  VARYING vec3 vary_position;
   84.49  VARYING vec3 vary_pointlight_col;
   84.50  
   84.51 +#ifdef USE_VERTEX_COLOR
   84.52  VARYING vec4 vertex_color;
   84.53 +#endif
   84.54 +
   84.55  VARYING vec2 vary_texcoord0;
   84.56  
   84.57 +VARYING vec3 vary_norm;
   84.58  
   84.59  uniform float near_clip;
   84.60 -uniform float shadow_offset;
   84.61 -uniform float shadow_bias;
   84.62  
   84.63  uniform vec4 light_position[8];
   84.64  uniform vec3 light_direction[8];
   84.65  uniform vec3 light_attenuation[8]; 
   84.66  uniform vec3 light_diffuse[8];
   84.67  
   84.68 -float calcDirectionalLight(vec3 n, vec3 l)
   84.69 -{
   84.70 -        float a = max(dot(n,l),0.0);
   84.71 -        return a;
   84.72 -}
   84.73 +uniform vec3 sun_dir;
   84.74  
   84.75 -float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
   84.76 +vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
   84.77  {
   84.78  	//get light vector
   84.79  	vec3 lv = lp.xyz-v;
   84.80 @@ -96,53 +113,110 @@
   84.81  		da *= max(dot(n, lv), 0.0);		
   84.82  	}
   84.83  
   84.84 -	return da;	
   84.85 +	return vec3(da,da,da);	
   84.86  }
   84.87  
   84.88  void main()
   84.89  {
   84.90 +	vec4 pos;
   84.91 +	vec3 norm;
   84.92 +	
   84.93  	//transform vertex
   84.94 +#ifdef HAS_SKIN
   84.95 +	mat4 trans = getObjectSkinnedTransform();
   84.96 +	trans = modelview_matrix * trans;
   84.97 +	
   84.98 +	pos = trans * vec4(position.xyz, 1.0);
   84.99 +	
  84.100 +	norm = position.xyz + normal.xyz;
  84.101 +	norm = normalize((trans * vec4(norm, 1.0)).xyz - pos.xyz);
  84.102 +	vec4 frag_pos = projection_matrix * pos;
  84.103 +	gl_Position = frag_pos;
  84.104 +#else
  84.105 +
  84.106 +#ifdef IS_AVATAR_SKIN
  84.107 +	mat4 trans = getSkinnedTransform();
  84.108 +	vec4 pos_in = vec4(position.xyz, 1.0);
  84.109 +	pos.x = dot(trans[0], pos_in);
  84.110 +	pos.y = dot(trans[1], pos_in);
  84.111 +	pos.z = dot(trans[2], pos_in);
  84.112 +	pos.w = 1.0;
  84.113 +	
  84.114 +	norm.x = dot(trans[0].xyz, normal);
  84.115 +	norm.y = dot(trans[1].xyz, normal);
  84.116 +	norm.z = dot(trans[2].xyz, normal);
  84.117 +	norm = normalize(norm);
  84.118 +	
  84.119 +	vec4 frag_pos = projection_matrix * pos;
  84.120 +	gl_Position = frag_pos;
  84.121 +#else
  84.122 +	norm = normalize(normal_matrix * normal);
  84.123  	vec4 vert = vec4(position.xyz, 1.0);
  84.124 +	pos = (modelview_matrix * vert);
  84.125 +	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
  84.126 +#endif
  84.127 +	
  84.128 +#endif
  84.129 +
  84.130 +#ifdef USE_INDEXED_TEX
  84.131  	passTextureIndex();
  84.132 -	vec4 pos = (modelview_matrix * vert);
  84.133 -	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
  84.134 +	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
  84.135 +#else
  84.136 +	vary_texcoord0 = texcoord0;
  84.137 +#endif
  84.138  	
  84.139 -	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
  84.140 -	
  84.141 -	vec3 norm = normalize(normal_matrix * normal);
  84.142 -	
  84.143 -	float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));
  84.144 -	vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset;
  84.145 -		
  84.146 +	vary_norm = norm;
  84.147 +	vary_position = pos.xyz;
  84.148 +
  84.149  	calcAtmospherics(pos.xyz);
  84.150  
  84.151 +#ifndef USE_VERTEX_COLOR
  84.152 +	vec4 diffuse_color = vec4(1,1,1,1);
  84.153 +#endif
  84.154  	//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
  84.155  	vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
  84.156 +	
  84.157 +	vec3 diff = diffuse_color.rgb;
  84.158  
  84.159 -	// Collect normal lights
  84.160 -	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);
  84.161 -	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);
  84.162 -	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);
  84.163 -	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);
  84.164 -	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);
  84.165 -	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);
  84.166  	
  84.167 -	vary_pointlight_col = col.rgb*diffuse_color.rgb;
  84.168 +
  84.169 +	vary_pointlight_col = diff;
  84.170 +
  84.171 +	
  84.172  	col.rgb = vec3(0,0,0);
  84.173  
  84.174  	// Add windlight lights
  84.175 -	col.rgb = atmosAmbient(vec3(0.));
  84.176 +	col.rgb = atmosAmbient(col.rgb);
  84.177  	
  84.178 -	vary_ambient = col.rgb*diffuse_color.rgb;
  84.179 -	vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
  84.180 +	float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
  84.181 +	ambient *= 0.5;
  84.182 +	ambient *= ambient;
  84.183 +	ambient = (1.0-ambient);
  84.184 +
  84.185 +	col.rgb *= ambient;
  84.186 +
  84.187 +	vary_ambient = col.rgb*diff.rgb;
  84.188 +
  84.189 +	vary_directional.rgb = atmosAffectDirectionalLight(1.0f);
  84.190  	
  84.191 -	col.rgb = col.rgb*diffuse_color.rgb;
  84.192 +	col.rgb = col.rgb*diff.rgb;
  84.193  	
  84.194 +#ifdef USE_VERTEX_COLOR
  84.195  	vertex_color = col;
  84.196 +#endif
  84.197 +	
  84.198 +#ifdef HAS_SKIN
  84.199 +	vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
  84.200 +#else
  84.201  
  84.202 -	
  84.203 -	
  84.204 +#ifdef IS_AVATAR_SKIN
  84.205 +	vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
  84.206 +#else
  84.207  	pos = modelview_projection_matrix * vert;
  84.208  	vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
  84.209 +#endif
  84.210  	
  84.211 +#endif
  84.212 +
  84.213  }
  84.214 +
    85.1 --- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl	Thu Jul 18 15:14:55 2013 -0400
    85.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl	Thu Jul 18 18:43:58 2013 -0400
    85.3 @@ -39,7 +39,12 @@
    85.4  	mat = modelview_matrix * mat;
    85.5  	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
    85.6  	
    85.7 +
    85.8  	vec4 p = projection_matrix * vec4(pos, 1.0);
    85.9 +#if !DEPTH_CLAMP
   85.10  	p.z = max(p.z, -p.w+0.01);
   85.11  	gl_Position = p;
   85.12 +#else
   85.13 +	gl_Position = p;
   85.14 +#endif
   85.15  }
    86.1 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl	Thu Jul 18 15:14:55 2013 -0400
    86.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl	Thu Jul 18 18:43:58 2013 -0400
    86.3 @@ -47,6 +47,7 @@
    86.4  VARYING vec3 vary_fragcoord;
    86.5  VARYING vec3 vary_pointlight_col;
    86.6  VARYING vec2 vary_texcoord0;
    86.7 +VARYING vec3 vary_norm;
    86.8  
    86.9  
   86.10  uniform float near_clip;
   86.11 @@ -112,6 +113,7 @@
   86.12  	norm.y = dot(trans[1].xyz, normal);
   86.13  	norm.z = dot(trans[2].xyz, normal);
   86.14  	norm = normalize(norm);
   86.15 +	vary_norm = norm;
   86.16  		
   86.17  	vec4 frag_pos = projection_matrix * pos;
   86.18  	gl_Position = frag_pos;
    87.1 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl	Thu Jul 18 15:14:55 2013 -0400
    87.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl	Thu Jul 18 18:43:58 2013 -0400
    87.3 @@ -34,6 +34,12 @@
    87.4  VARYING vec3 vary_normal;
    87.5  VARYING vec2 vary_texcoord0;
    87.6  
    87.7 +vec2 encode_normal(vec3 n)
    87.8 +{
    87.9 +	float f = sqrt(8 * n.z + 8);
   87.10 +	return n.xy / f + 0.5;
   87.11 +}
   87.12 +
   87.13  void main() 
   87.14  {
   87.15  	vec4 diff = texture2D(diffuseMap, vary_texcoord0.xy);
   87.16 @@ -46,6 +52,6 @@
   87.17  	frag_data[0] = vec4(diff.rgb, 0.0);
   87.18  	frag_data[1] = vec4(0,0,0,0);
   87.19  	vec3 nvn = normalize(vary_normal);
   87.20 -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
   87.21 +	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
   87.22  }
   87.23  
    88.1 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl	Thu Jul 18 15:14:55 2013 -0400
    88.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl	Thu Jul 18 18:43:58 2013 -0400
    88.3 @@ -31,12 +31,16 @@
    88.4  
    88.5  uniform sampler2D diffuseMap;
    88.6  
    88.7 +#if !DEPTH_CLAMP
    88.8  VARYING vec4 post_pos;
    88.9 +#endif
   88.10  
   88.11  void main() 
   88.12  {
   88.13  	frag_color = vec4(1,1,1,1);
   88.14  
   88.15 +#if !DEPTH_CLAMP
   88.16  	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
   88.17 +#endif
   88.18  }
   88.19  
    89.1 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl	Thu Jul 18 15:14:55 2013 -0400
    89.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl	Thu Jul 18 18:43:58 2013 -0400
    89.3 @@ -31,7 +31,9 @@
    89.4  ATTRIBUTE vec3 normal;
    89.5  ATTRIBUTE vec2 texcoord0;
    89.6  
    89.7 +#if !DEPTH_CLAMP
    89.8  VARYING vec4 post_pos;
    89.9 +#endif
   89.10  
   89.11  void main()
   89.12  {
   89.13 @@ -51,9 +53,13 @@
   89.14  	norm = normalize(norm);
   89.15  	
   89.16  	pos = projection_matrix * pos;
   89.17 +#if !DEPTH_CLAMP
   89.18  	post_pos = pos;
   89.19  
   89.20  	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
   89.21 +#else
   89.22 +	gl_Position = pos;
   89.23 +#endif
   89.24  }
   89.25  
   89.26  
    90.1 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl	Thu Jul 18 15:14:55 2013 -0400
    90.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl	Thu Jul 18 18:43:58 2013 -0400
    90.3 @@ -46,11 +46,6 @@
    90.4  uniform mat4 inv_proj;
    90.5  uniform vec2 screen_res;
    90.6  
    90.7 -vec3 getKern(int i)
    90.8 -{
    90.9 -	return kern[i];
   90.10 -}
   90.11 -
   90.12  vec4 getPosition(vec2 pos_screen)
   90.13  {
   90.14  	float depth = texture2DRect(depthMap, pos_screen.xy).r;
   90.15 @@ -64,18 +59,53 @@
   90.16  	return pos;
   90.17  }
   90.18  
   90.19 +#ifdef SINGLE_FP_ONLY
   90.20 +vec2 encode_normal(vec3 n)
   90.21 +{
   90.22 +	vec2 sn;
   90.23 +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
   90.24 +	return sn;
   90.25 +}
   90.26 +
   90.27 +vec3 decode_normal (vec2 enc)
   90.28 +{
   90.29 +	vec3 n;
   90.30 +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
   90.31 +	n.z = sqrt(1.0f - dot(n.xy,n.xy));
   90.32 +	return n;
   90.33 +}
   90.34 +#else
   90.35 +vec2 encode_normal(vec3 n)
   90.36 +{
   90.37 +	float f = sqrt(8 * n.z + 8);
   90.38 +	return n.xy / f + 0.5;
   90.39 +}
   90.40 +
   90.41 +vec3 decode_normal (vec2 enc)
   90.42 +{
   90.43 +    vec2 fenc = enc*4-2;
   90.44 +    float f = dot(fenc,fenc);
   90.45 +    float g = sqrt(1-f/4);
   90.46 +    vec3 n;
   90.47 +    n.xy = fenc*g;
   90.48 +    n.z = 1-f/2;
   90.49 +    return n;
   90.50 +}
   90.51 +#endif
   90.52 +
   90.53  void main() 
   90.54  {
   90.55      vec2 tc = vary_fragcoord.xy;
   90.56  	vec3 norm = texture2DRect(normalMap, tc).xyz;
   90.57 -	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
   90.58 +	norm = decode_normal(norm.xy); // unpack norm
   90.59 +
   90.60  	vec3 pos = getPosition(tc).xyz;
   90.61  	vec4 ccol = texture2DRect(lightMap, tc).rgba;
   90.62  	
   90.63  	vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy);
   90.64  	dlt /= max(-pos.z*dist_factor, 1.0);
   90.65  	
   90.66 -	vec2 defined_weight = getKern(0).xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
   90.67 +	vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
   90.68  	vec4 col = defined_weight.xyxx * ccol;
   90.69  
   90.70  	// relax tolerance according to distance to avoid speckling artifacts, as angles and distances are a lot more abrupt within a small screen area at larger distances
   90.71 @@ -85,28 +115,33 @@
   90.72  	float tc_mod = 0.5*(tc.x + tc.y); // mod(tc.x+tc.y,2)
   90.73  	tc_mod -= floor(tc_mod);
   90.74  	tc_mod *= 2.0;
   90.75 -	tc += ( (tc_mod - 0.5) * getKern(1).z * dlt * 0.5 );
   90.76 +	tc += ( (tc_mod - 0.5) * kern[1].z * dlt * 0.5 );
   90.77  
   90.78  	for (int i = 1; i < 4; i++)
   90.79  	{
   90.80 -		vec2 samptc = tc + getKern(i).z*dlt;
   90.81 -	        vec3 samppos = getPosition(samptc).xyz; 
   90.82 +		vec2 samptc = tc + kern[i].z*dlt;
   90.83 +	    vec3 samppos = getPosition(samptc).xyz; 
   90.84 +
   90.85  		float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
   90.86 +		
   90.87  		if (d*d <= pointplanedist_tolerance_pow2)
   90.88  		{
   90.89 -			col += texture2DRect(lightMap, samptc)*getKern(i).xyxx;
   90.90 -			defined_weight += getKern(i).xy;
   90.91 +			col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
   90.92 +			defined_weight += kern[i].xy;
   90.93  		}
   90.94  	}
   90.95 +
   90.96  	for (int i = 1; i < 4; i++)
   90.97  	{
   90.98 -		vec2 samptc = tc - getKern(i).z*dlt;
   90.99 -	        vec3 samppos = getPosition(samptc).xyz; 
  90.100 +		vec2 samptc = tc - kern[i].z*dlt;
  90.101 +	    vec3 samppos = getPosition(samptc).xyz; 
  90.102 +
  90.103  		float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
  90.104 +		
  90.105  		if (d*d <= pointplanedist_tolerance_pow2)
  90.106  		{
  90.107 -			col += texture2DRect(lightMap, samptc)*getKern(i).xyxx;
  90.108 -			defined_weight += getKern(i).xy;
  90.109 +			col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
  90.110 +			defined_weight += kern[i].xy;
  90.111  		}
  90.112  	}
  90.113  
    91.1 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl	Thu Jul 18 15:14:55 2013 -0400
    91.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl	Thu Jul 18 18:43:58 2013 -0400
    91.3 @@ -39,6 +39,12 @@
    91.4  VARYING vec4 vertex_color;
    91.5  VARYING vec2 vary_texcoord0;
    91.6  
    91.7 +vec2 encode_normal(vec3 n)
    91.8 +{
    91.9 +	float f = sqrt(8 * n.z + 8);
   91.10 +	return n.xy / f + 0.5;
   91.11 +}
   91.12 +
   91.13  void main() 
   91.14  {
   91.15  	vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb;
   91.16 @@ -52,5 +58,5 @@
   91.17  	frag_data[1] = vertex_color.aaaa; // spec
   91.18  	//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
   91.19  	vec3 nvn = normalize(tnorm);
   91.20 -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
   91.21 +	frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
   91.22  }
    92.1 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl	Thu Jul 18 15:14:55 2013 -0400
    92.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl	Thu Jul 18 18:43:58 2013 -0400
    92.3 @@ -30,7 +30,7 @@
    92.4  ATTRIBUTE vec4 diffuse_color;
    92.5  ATTRIBUTE vec3 normal;
    92.6  ATTRIBUTE vec2 texcoord0;
    92.7 -ATTRIBUTE vec3 binormal;
    92.8 +ATTRIBUTE vec4 tangent;
    92.9  
   92.10  VARYING vec3 vary_mat0;
   92.11  VARYING vec3 vary_mat1;
   92.12 @@ -52,8 +52,8 @@
   92.13  	
   92.14  	
   92.15  	vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz);
   92.16 -	vec3 b = normalize((mat * vec4(binormal.xyz+position.xyz, 1.0)).xyz-pos.xyz);
   92.17 -	vec3 t = cross(b, n);
   92.18 +	vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz);
   92.19 +	vec3 b = cross(n, t) * tangent.w;
   92.20  	
   92.21  	vary_mat0 = vec3(t.x, b.x, n.x);
   92.22  	vary_mat1 = vec3(t.y, b.y, n.y);
    93.1 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl	Thu Jul 18 15:14:55 2013 -0400
    93.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl	Thu Jul 18 18:43:58 2013 -0400
    93.3 @@ -31,7 +31,7 @@
    93.4  ATTRIBUTE vec4 diffuse_color;
    93.5  ATTRIBUTE vec3 normal;
    93.6  ATTRIBUTE vec2 texcoord0;
    93.7 -ATTRIBUTE vec3 binormal;
    93.8 +ATTRIBUTE vec4 tangent;
    93.9  
   93.10  VARYING vec3 vary_mat0;
   93.11  VARYING vec3 vary_mat1;
   93.12 @@ -46,8 +46,8 @@
   93.13  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
   93.14  	
   93.15  	vec3 n = normalize(normal_matrix * normal);
   93.16 -	vec3 b = normalize(normal_matrix * binormal);
   93.17 -	vec3 t = cross(b, n);
   93.18 +	vec3 t = normalize(normal_matrix * tangent.xyz);
   93.19 +	vec3 b = cross(n, t) * tangent.w;
   93.20  	
   93.21  	vary_mat0 = vec3(t.x, b.x, n.x);
   93.22  	vary_mat1 = vec3(t.y, b.y, n.y);
    94.1 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl	Thu Jul 18 15:14:55 2013 -0400
    94.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl	Thu Jul 18 18:43:58 2013 -0400
    94.3 @@ -37,6 +37,12 @@
    94.4  VARYING vec4 vertex_color;
    94.5  VARYING vec2 vary_texcoord0;
    94.6  
    94.7 +vec2 encode_normal(vec3 n)
    94.8 +{
    94.9 +	float f = sqrt(8 * n.z + 8);
   94.10 +	return n.xy / f + 0.5;
   94.11 +}
   94.12 +
   94.13  void main() 
   94.14  {
   94.15  	vec4 col = texture2D(diffuseMap, vary_texcoord0.xy) * vertex_color;
   94.16 @@ -49,6 +55,6 @@
   94.17  	frag_data[0] = vec4(col.rgb, 0.0);
   94.18  	frag_data[1] = vec4(0,0,0,0); // spec
   94.19  	vec3 nvn = normalize(vary_normal);
   94.20 -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
   94.21 +	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
   94.22  }
   94.23  
    95.1 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl	Thu Jul 18 15:14:55 2013 -0400
    95.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl	Thu Jul 18 18:43:58 2013 -0400
    95.3 @@ -36,6 +36,12 @@
    95.4  VARYING vec4 vertex_color;
    95.5  VARYING vec2 vary_texcoord0;
    95.6  
    95.7 +vec2 encode_normal(vec3 n)
    95.8 +{
    95.9 +	float f = sqrt(8 * n.z + 8);
   95.10 +	return n.xy / f + 0.5;
   95.11 +}
   95.12 +
   95.13  void main() 
   95.14  {
   95.15  	vec4 col = diffuseLookup(vary_texcoord0.xy) * vertex_color;
   95.16 @@ -48,5 +54,5 @@
   95.17  	frag_data[0] = vec4(col.rgb, 0.0);
   95.18  	frag_data[1] = vec4(0,0,0,0);
   95.19  	vec3 nvn = normalize(vary_normal);
   95.20 -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
   95.21 +	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
   95.22  }
    96.1 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl	Thu Jul 18 15:14:55 2013 -0400
    96.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl	Thu Jul 18 18:43:58 2013 -0400
    96.3 @@ -37,6 +37,12 @@
    96.4  VARYING vec3 vary_normal;
    96.5  VARYING vec2 vary_texcoord0;
    96.6  
    96.7 +vec2 encode_normal(vec3 n)
    96.8 +{
    96.9 +	float f = sqrt(8 * n.z + 8);
   96.10 +	return n.xy / f + 0.5;
   96.11 +}
   96.12 +
   96.13  void main() 
   96.14  {
   96.15  	vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
   96.16 @@ -49,6 +55,6 @@
   96.17  	frag_data[0] = vec4(col.rgb, 0.0);
   96.18  	frag_data[1] = vec4(0,0,0,0); // spec
   96.19  	vec3 nvn = normalize(vary_normal);
   96.20 -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
   96.21 +	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
   96.22  }
   96.23  
    97.1 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl	Thu Jul 18 15:14:55 2013 -0400
    97.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl	Thu Jul 18 18:43:58 2013 -0400
    97.3 @@ -35,6 +35,12 @@
    97.4  VARYING vec4 vertex_color;
    97.5  VARYING vec2 vary_texcoord0;
    97.6  
    97.7 +vec2 encode_normal(vec3 n)
    97.8 +{
    97.9 +	float f = sqrt(8 * n.z + 8);
   97.10 +	return n.xy / f + 0.5;
   97.11 +}
   97.12 +
   97.13  void main() 
   97.14  {
   97.15  	vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb;
   97.16 @@ -42,6 +48,6 @@
   97.17  	frag_data[1] = vertex_color.aaaa; // spec
   97.18  	//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
   97.19  	vec3 nvn = normalize(vary_normal);
   97.20 -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
   97.21 +	frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
   97.22  }
   97.23  
    98.1 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl	Thu Jul 18 15:14:55 2013 -0400
    98.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl	Thu Jul 18 18:43:58 2013 -0400
    98.3 @@ -33,13 +33,22 @@
    98.4  VARYING vec4 vertex_color;
    98.5  VARYING vec2 vary_texcoord0;
    98.6  
    98.7 +vec2 encode_normal(vec3 n)
    98.8 +{
    98.9 +	float f = sqrt(8 * n.z + 8);
   98.10 +	return n.xy / f + 0.5;
   98.11 +}
   98.12 +
   98.13 +
   98.14  void main() 
   98.15  {
   98.16  	vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
   98.17 +	
   98.18 +	vec3 spec;
   98.19 +	spec.rgb = vec3(vertex_color.a);
   98.20  
   98.21  	frag_data[0] = vec4(col, 0.0);
   98.22 -	frag_data[1] = vertex_color.aaaa; // spec
   98.23 -	//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
   98.24 +	frag_data[1] = vec4(spec, vertex_color.a); // spec
   98.25  	vec3 nvn = normalize(vary_normal);
   98.26 -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
   98.27 +	frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
   98.28  }
    99.1 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl	Thu Jul 18 15:14:55 2013 -0400
    99.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl	Thu Jul 18 18:43:58 2013 -0400
    99.3 @@ -47,6 +47,6 @@
    99.4  	
    99.5  	passTextureIndex();
    99.6  	vary_normal = normalize(normal_matrix * normal);
    99.7 -
    99.8 +	
    99.9  	vertex_color = diffuse_color;
   99.10  }
   100.1 --- a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl	Thu Jul 18 15:14:55 2013 -0400
   100.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl	Thu Jul 18 18:43:58 2013 -0400
   100.3 @@ -42,7 +42,7 @@
   100.4  	float shadow = 1.0;
   100.5  
   100.6  	vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
   100.7 -	
   100.8 +	color.rgb = pow(color.rgb, vec3(2.2));
   100.9  	color.rgb = fullbrightAtmosTransport(color.rgb);
  100.10  
  100.11  	color.rgb = fullbrightScaleSoftClip(color.rgb);
   101.1 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl	Thu Jul 18 15:14:55 2013 -0400
   101.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl	Thu Jul 18 18:43:58 2013 -0400
   101.3 @@ -31,6 +31,10 @@
   101.4  #define frag_color gl_FragColor
   101.5  #endif
   101.6  
   101.7 +#if !HAS_DIFFUSE_LOOKUP
   101.8 +uniform sampler2D diffuseMap;
   101.9 +#endif
  101.10 +
  101.11  VARYING vec4 vertex_color;
  101.12  VARYING vec2 vary_texcoord0;
  101.13  
  101.14 @@ -40,14 +44,20 @@
  101.15  
  101.16  void main() 
  101.17  {
  101.18 -	float shadow = 1.0;
  101.19 +#if HAS_DIFFUSE_LOOKUP
  101.20 +	vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
  101.21 +#else
  101.22 +	vec4 color = texture2D(diffuseMap, vary_texcoord0.xy)*vertex_color;
  101.23 +#endif
  101.24  
  101.25 -	vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
  101.26 +	color.rgb = pow(color.rgb,vec3(2.2f,2.2f,2.2f));
  101.27  	
  101.28  	color.rgb = fullbrightAtmosTransport(color.rgb);
  101.29  
  101.30  	color.rgb = fullbrightScaleSoftClip(color.rgb);
  101.31  
  101.32 +	color.rgb = pow(color.rgb, vec3(1.0/2.2));
  101.33 +
  101.34  	frag_color = color;
  101.35  }
  101.36  
   102.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl	Thu Jul 18 18:43:58 2013 -0400
   102.3 @@ -0,0 +1,72 @@
   102.4 +/** 
   102.5 + * @file fullbrightShinyF.glsl
   102.6 + *
   102.7 + * $LicenseInfo:firstyear=2007&license=viewerlgpl$
   102.8 + * Second Life Viewer Source Code
   102.9 + * Copyright (C) 2007, Linden Research, Inc.
  102.10 + * 
  102.11 + * This library is free software; you can redistribute it and/or
  102.12 + * modify it under the terms of the GNU Lesser General Public
  102.13 + * License as published by the Free Software Foundation;
  102.14 + * version 2.1 of the License only.
  102.15 + * 
  102.16 + * This library is distributed in the hope that it will be useful,
  102.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  102.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  102.19 + * Lesser General Public License for more details.
  102.20 + * 
  102.21 + * You should have received a copy of the GNU Lesser General Public
  102.22 + * License along with this library; if not, write to the Free Software
  102.23 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  102.24 + * 
  102.25 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  102.26 + * $/LicenseInfo$
  102.27 + */
  102.28 + 
  102.29 +
  102.30 +
  102.31 +#ifdef DEFINE_GL_FRAGCOLOR
  102.32 +out vec4 frag_color;
  102.33 +#else
  102.34 +#define frag_color gl_FragColor
  102.35 +#endif
  102.36 +
  102.37 +#ifndef diffuseLookup
  102.38 +uniform sampler2D diffuseMap;
  102.39 +#endif
  102.40 +
  102.41 +VARYING vec4 vertex_color;
  102.42 +VARYING vec2 vary_texcoord0;
  102.43 +VARYING vec3 vary_texcoord1;
  102.44 +
  102.45 +uniform samplerCube environmentMap;
  102.46 +
  102.47 +vec3 fullbrightShinyAtmosTransport(vec3 light);
  102.48 +vec3 fullbrightScaleSoftClip(vec3 light);
  102.49 +
  102.50 +void main()
  102.51 +{
  102.52 +#if HAS_DIFFUSE_LOOKUP
  102.53 +	vec4 color = diffuseLookup(vary_texcoord0.xy);
  102.54 +#else
  102.55 +	vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
  102.56 +#endif
  102.57 +
  102.58 +	
  102.59 +	color.rgb *= vertex_color.rgb;
  102.60 +	
  102.61 +	vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;	
  102.62 +	color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
  102.63 +
  102.64 +	color.rgb = pow(color.rgb,vec3(2.2f,2.2f,2.2f));
  102.65 +	
  102.66 +	color.rgb = fullbrightShinyAtmosTransport(color.rgb);
  102.67 +	color.rgb = fullbrightScaleSoftClip(color.rgb);
  102.68 +
  102.69 +	color.a = 1.0;
  102.70 +
  102.71 +	color.rgb = pow(color.rgb, vec3(1.0/2.2));
  102.72 +
  102.73 +	frag_color = color;
  102.74 +}
  102.75 +
   103.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   103.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl	Thu Jul 18 18:43:58 2013 -0400
   103.3 @@ -0,0 +1,67 @@
   103.4 +/**
   103.5 + * @file fullbrightShinyV.glsl
   103.6 + *
   103.7 + * $LicenseInfo:firstyear=2007&license=viewerlgpl$
   103.8 + * Second Life Viewer Source Code
   103.9 + * Copyright (C) 2007, Linden Research, Inc.
  103.10 + * 
  103.11 + * This library is free software; you can redistribute it and/or
  103.12 + * modify it under the terms of the GNU Lesser General Public
  103.13 + * License as published by the Free Software Foundation;
  103.14 + * version 2.1 of the License only.
  103.15 + * 
  103.16 + * This library is distributed in the hope that it will be useful,
  103.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  103.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  103.19 + * Lesser General Public License for more details.
  103.20 + * 
  103.21 + * You should have received a copy of the GNU Lesser General Public
  103.22 + * License along with this library; if not, write to the Free Software
  103.23 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  103.24 + * 
  103.25 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  103.26 + * $/LicenseInfo$
  103.27 + */
  103.28 +
  103.29 +uniform mat3 normal_matrix;
  103.30 +uniform mat4 texture_matrix0;
  103.31 +uniform mat4 texture_matrix1;
  103.32 +uniform mat4 modelview_matrix;
  103.33 +uniform mat4 modelview_projection_matrix;
  103.34 +
  103.35 +
  103.36 +void calcAtmospherics(vec3 inPositionEye);
  103.37 +
  103.38 +uniform vec4 origin;
  103.39 +
  103.40 +
  103.41 +
  103.42 +ATTRIBUTE vec3 position;
  103.43 +void passTextureIndex();
  103.44 +ATTRIBUTE vec3 normal;
  103.45 +ATTRIBUTE vec4 diffuse_color;
  103.46 +ATTRIBUTE vec2 texcoord0;
  103.47 +
  103.48 +VARYING vec4 vertex_color;
  103.49 +VARYING vec2 vary_texcoord0;
  103.50 +VARYING vec3 vary_texcoord1;
  103.51 +
  103.52 +
  103.53 +void main()
  103.54 +{
  103.55 +	//transform vertex
  103.56 +	vec4 vert = vec4(position.xyz,1.0);
  103.57 +	passTextureIndex();
  103.58 +	vec4 pos = (modelview_matrix * vert);
  103.59 +	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
  103.60 +	
  103.61 +	vec3 norm = normalize(normal_matrix * normal);
  103.62 +	vec3 ref = reflect(pos.xyz, -norm);
  103.63 +
  103.64 +	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
  103.65 +	vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz;
  103.66 +
  103.67 +	calcAtmospherics(pos.xyz);
  103.68 +
  103.69 +	vertex_color = diffuse_color;
  103.70 +}
   104.1 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl	Thu Jul 18 15:14:55 2013 -0400
   104.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl	Thu Jul 18 18:43:58 2013 -0400
   104.3 @@ -57,8 +57,6 @@
   104.4  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
   104.5  	
   104.6  	calcAtmospherics(pos.xyz);
   104.7 -	
   104.8 +
   104.9  	vertex_color = diffuse_color;
  104.10 -
  104.11 -	
  104.12  }
   105.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   105.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl	Thu Jul 18 18:43:58 2013 -0400
   105.3 @@ -0,0 +1,696 @@
   105.4 +/** 
   105.5 + * @file materialF.glsl
   105.6 + *
   105.7 + * $LicenseInfo:firstyear=2007&license=viewerlgpl$
   105.8 + * Second Life Viewer Source Code
   105.9 + * Copyright (C) 2007, Linden Research, Inc.
  105.10 + * 
  105.11 + * This library is free software; you can redistribute it and/or
  105.12 + * modify it under the terms of the GNU Lesser General Public
  105.13 + * License as published by the Free Software Foundation;
  105.14 + * version 2.1 of the License only.
  105.15 + * 
  105.16 + * This library is distributed in the hope that it will be useful,
  105.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  105.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  105.19 + * Lesser General Public License for more details.
  105.20 + * 
  105.21 + * You should have received a copy of the GNU Lesser General Public
  105.22 + * License along with this library; if not, write to the Free Software
  105.23 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  105.24 + * 
  105.25 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  105.26 + * $/LicenseInfo$
  105.27 + */
  105.28 + 
  105.29 +#define DIFFUSE_ALPHA_MODE_IGNORE	0
  105.30 +#define DIFFUSE_ALPHA_MODE_BLEND	1
  105.31 +#define DIFFUSE_ALPHA_MODE_MASK		2
  105.32 +#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
  105.33 +
  105.34 +uniform float emissive_brightness;
  105.35 +
  105.36 +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
  105.37 +
  105.38 +#ifdef DEFINE_GL_FRAGCOLOR
  105.39 +out vec4 frag_color;
  105.40 +#else
  105.41 +#define frag_color gl_FragColor
  105.42 +#endif
  105.43 +
  105.44 +#if HAS_SUN_SHADOW
  105.45 +
  105.46 +uniform sampler2DShadow shadowMap0;
  105.47 +uniform sampler2DShadow shadowMap1;
  105.48 +uniform sampler2DShadow shadowMap2;
  105.49 +uniform sampler2DShadow shadowMap3;
  105.50 +
  105.51 +uniform mat4 shadow_matrix[6];
  105.52 +uniform vec4 shadow_clip;
  105.53 +uniform vec2 shadow_res;
  105.54 +uniform float shadow_bias;
  105.55 +
  105.56 +float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
  105.57 +{
  105.58 +	stc.xyz /= stc.w;
  105.59 +	stc.z += shadow_bias;
  105.60 +		
  105.61 +	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
  105.62 +	
  105.63 +	float cs = shadow2D(shadowMap, stc.xyz).x;
  105.64 +	float shadow = cs;
  105.65 +	
  105.66 +    shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
  105.67 +    shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
  105.68 +    shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
  105.69 +    shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
  105.70 +                       
  105.71 +    return shadow*0.2;
  105.72 +}
  105.73 +
  105.74 +#endif
  105.75 +
  105.76 +uniform samplerCube environmentMap;
  105.77 +uniform sampler2D	  lightFunc;
  105.78 +
  105.79 +// Inputs
  105.80 +uniform vec4 morphFactor;
  105.81 +uniform vec3 camPosLocal;
  105.82 +//uniform vec4 camPosWorld;
  105.83 +uniform vec4 gamma;
  105.84 +uniform vec4 lightnorm;
  105.85 +uniform vec4 sunlight_color;
  105.86 +uniform vec4 ambient;
  105.87 +uniform vec4 blue_horizon;
  105.88 +uniform vec4 blue_density;
  105.89 +uniform float haze_horizon;
  105.90 +uniform float haze_density;
  105.91 +uniform float cloud_shadow;
  105.92 +uniform float density_multiplier;
  105.93 +uniform float distance_multiplier;
  105.94 +uniform float max_y;
  105.95 +uniform vec4 glow;
  105.96 +uniform float scene_light_strength;
  105.97 +uniform mat3 env_mat;
  105.98 +uniform mat3 ssao_effect_mat;
  105.99 +
 105.100 +uniform vec3 sun_dir;
 105.101 +VARYING vec2 vary_fragcoord;
 105.102 +
 105.103 +VARYING vec3 vary_position;
 105.104 +
 105.105 +vec3 vary_PositionEye;
 105.106 +
 105.107 +vec3 vary_SunlitColor;
 105.108 +vec3 vary_AmblitColor;
 105.109 +vec3 vary_AdditiveColor;
 105.110 +vec3 vary_AtmosAttenuation;
 105.111 +
 105.112 +uniform mat4 inv_proj;
 105.113 +uniform vec2 screen_res;
 105.114 +
 105.115 +uniform vec4 light_position[8];
 105.116 +uniform vec3 light_direction[8];
 105.117 +uniform vec3 light_attenuation[8]; 
 105.118 +uniform vec3 light_diffuse[8];
 105.119 +
 105.120 +vec3 calcDirectionalLight(vec3 n, vec3 l)
 105.121 +{
 105.122 +	float a = max(dot(n,l),0.0);
 105.123 +	return vec3(a,a,a);
 105.124 +}
 105.125 +
 105.126 +
 105.127 +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)
 105.128 +{
 105.129 +	//get light vector
 105.130 +	vec3 lv = lp.xyz-v;
 105.131 +	
 105.132 +	//get distance
 105.133 +	float d = length(lv);
 105.134 +	
 105.135 +	float da = 1.0;
 105.136 +
 105.137 +	vec3 col = vec3(0,0,0);
 105.138 +
 105.139 +	if (d > 0.0 && la > 0.0 && fa > 0.0)
 105.140 +	{
 105.141 +		//normalize light vector
 105.142 +		lv = normalize(lv);
 105.143 +	
 105.144 +		//distance attenuation
 105.145 +		float dist = d/la;
 105.146 +		float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
 105.147 +		dist_atten *= dist_atten;
 105.148 +		dist_atten *= 1.4;
 105.149 +
 105.150 +		// spotlight coefficient.
 105.151 +		float spot = max(dot(-ln, lv), is_pointlight);
 105.152 +		da *= spot*spot; // GL_SPOT_EXPONENT=2
 105.153 +
 105.154 +		//angular attenuation
 105.155 +		da *= max(dot(n, lv), 0.0);		
 105.156 +		
 105.157 +		float lit = max(da * dist_atten, 0.0);
 105.158 +
 105.159 +		col = light_col*lit*diffuse;
 105.160 +
 105.161 +		if (spec.a > 0.0)
 105.162 +		{
 105.163 +			//vec3 ref = dot(pos+lv, norm);
 105.164 +			vec3 h = normalize(lv+npos);
 105.165 +			float nh = dot(n, h);
 105.166 +			float nv = dot(n, npos);
 105.167 +			float vh = dot(npos, h);
 105.168 +			float sa = nh;
 105.169 +			float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
 105.170 +
 105.171 +			float gtdenom = 2 * nh;
 105.172 +			float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
 105.173 +								
 105.174 +			if (nh > 0.0)
 105.175 +			{
 105.176 +				float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
 105.177 +				vec3 speccol = lit*scol*light_col.rgb*spec.rgb;
 105.178 +				col += speccol;
 105.179 +
 105.180 +				float cur_glare = max(speccol.r, speccol.g);
 105.181 +				cur_glare = max(cur_glare, speccol.b);
 105.182 +				glare = max(glare, speccol.r);
 105.183 +				glare += max(cur_glare, 0.0);
 105.184 +				//col += spec.rgb;
 105.185 +			}
 105.186 +		}
 105.187 +	}
 105.188 +
 105.189 +	return max(col, vec3(0.0,0.0,0.0));	
 105.190 +
 105.191 +}
 105.192 +
 105.193 +vec4 getPosition_d(vec2 pos_screen, float depth)
 105.194 +{
 105.195 +	vec2 sc = pos_screen.xy*2.0;
 105.196 +	sc /= screen_res;
 105.197 +	sc -= vec2(1.0,1.0);
 105.198 +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
 105.199 +	vec4 pos = inv_proj * ndc;
 105.200 +	pos /= pos.w;
 105.201 +	pos.w = 1.0;
 105.202 +	return pos;
 105.203 +}
 105.204 +
 105.205 +vec3 getPositionEye()
 105.206 +{
 105.207 +	return vary_PositionEye;
 105.208 +}
 105.209 +vec3 getSunlitColor()
 105.210 +{
 105.211 +	return vary_SunlitColor;
 105.212 +}
 105.213 +vec3 getAmblitColor()
 105.214 +{
 105.215 +	return vary_AmblitColor;
 105.216 +}
 105.217 +vec3 getAdditiveColor()
 105.218 +{
 105.219 +	return vary_AdditiveColor;
 105.220 +}
 105.221 +vec3 getAtmosAttenuation()
 105.222 +{
 105.223 +	return vary_AtmosAttenuation;
 105.224 +}
 105.225 +
 105.226 +void setPositionEye(vec3 v)
 105.227 +{
 105.228 +	vary_PositionEye = v;
 105.229 +}
 105.230 +
 105.231 +void setSunlitColor(vec3 v)
 105.232 +{
 105.233 +	vary_SunlitColor = v;
 105.234 +}
 105.235 +
 105.236 +void setAmblitColor(vec3 v)
 105.237 +{
 105.238 +	vary_AmblitColor = v;
 105.239 +}
 105.240 +
 105.241 +void setAdditiveColor(vec3 v)
 105.242 +{
 105.243 +	vary_AdditiveColor = v;
 105.244 +}
 105.245 +
 105.246 +void setAtmosAttenuation(vec3 v)
 105.247 +{
 105.248 +	vary_AtmosAttenuation = v;
 105.249 +}
 105.250 +
 105.251 +void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
 105.252 +
 105.253 +	vec3 P = inPositionEye;
 105.254 +	setPositionEye(P);
 105.255 +	
 105.256 +	vec3 tmpLightnorm = lightnorm.xyz;
 105.257 +
 105.258 +	vec3 Pn = normalize(P);
 105.259 +	float Plen = length(P);
 105.260 +
 105.261 +	vec4 temp1 = vec4(0);
 105.262 +	vec3 temp2 = vec3(0);
 105.263 +	vec4 blue_weight;
 105.264 +	vec4 haze_weight;
 105.265 +	vec4 sunlight = sunlight_color;
 105.266 +	vec4 light_atten;
 105.267 +
 105.268 +	//sunlight attenuation effect (hue and brightness) due to atmosphere
 105.269 +	//this is used later for sunlight modulation at various altitudes
 105.270 +	light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
 105.271 +		//I had thought blue_density and haze_density should have equal weighting,
 105.272 +		//but attenuation due to haze_density tends to seem too strong
 105.273 +
 105.274 +	temp1 = blue_density + vec4(haze_density);
 105.275 +	blue_weight = blue_density / temp1;
 105.276 +	haze_weight = vec4(haze_density) / temp1;
 105.277 +
 105.278 +	//(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
 105.279 +	temp2.y = max(0.0, tmpLightnorm.y);
 105.280 +	temp2.y = 1. / temp2.y;
 105.281 +	sunlight *= exp( - light_atten * temp2.y);
 105.282 +
 105.283 +	// main atmospheric scattering line integral
 105.284 +	temp2.z = Plen * density_multiplier;
 105.285 +
 105.286 +	// Transparency (-> temp1)
 105.287 +	// ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
 105.288 +	// compiler gets confused.
 105.289 +	temp1 = exp(-temp1 * temp2.z * distance_multiplier);
 105.290 +
 105.291 +	//final atmosphere attenuation factor
 105.292 +	setAtmosAttenuation(temp1.rgb);
 105.293 +	
 105.294 +	//compute haze glow
 105.295 +	//(can use temp2.x as temp because we haven't used it yet)
 105.296 +	temp2.x = dot(Pn, tmpLightnorm.xyz);
 105.297 +	temp2.x = 1. - temp2.x;
 105.298 +		//temp2.x is 0 at the sun and increases away from sun
 105.299 +	temp2.x = max(temp2.x, .03);	//was glow.y
 105.300 +		//set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
 105.301 +	temp2.x *= glow.x;
 105.302 +		//higher glow.x gives dimmer glow (because next step is 1 / "angle")
 105.303 +	temp2.x = pow(temp2.x, glow.z);
 105.304 +		//glow.z should be negative, so we're doing a sort of (1 / "angle") function
 105.305 +
 105.306 +	//add "minimum anti-solar illumination"
 105.307 +	temp2.x += .25;
 105.308 +	
 105.309 +	//increase ambient when there are more clouds
 105.310 +	vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
 105.311 +	
 105.312 +	/*  decrease value and saturation (that in HSV, not HSL) for occluded areas
 105.313 +	 * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
 105.314 +	 * // The following line of code performs the equivalent of:
 105.315 +	 * float ambAlpha = tmpAmbient.a;
 105.316 +	 * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
 105.317 +	 * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
 105.318 +	 * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
 105.319 +	 */
 105.320 +	tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
 105.321 +
 105.322 +	//haze color
 105.323 +	setAdditiveColor(
 105.324 +		vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
 105.325 +	  + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
 105.326 +		  + tmpAmbient)));
 105.327 +
 105.328 +	//brightness of surface both sunlight and ambient
 105.329 +	setSunlitColor(vec3(sunlight * .5));
 105.330 +	setAmblitColor(vec3(tmpAmbient * .25));
 105.331 +	setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
 105.332 +}
 105.333 +
 105.334 +vec3 atmosLighting(vec3 light)
 105.335 +{
 105.336 +	light *= getAtmosAttenuation().r;
 105.337 +	light += getAdditiveColor();
 105.338 +	return (2.0 * light);
 105.339 +}
 105.340 +
 105.341 +vec3 atmosTransport(vec3 light) {
 105.342 +	light *= getAtmosAttenuation().r;
 105.343 +	light += getAdditiveColor() * 2.0;
 105.344 +	return light;
 105.345 +}
 105.346 +vec3 atmosGetDiffuseSunlightColor()
 105.347 +{
 105.348 +	return getSunlitColor();
 105.349 +}
 105.350 +
 105.351 +vec3 scaleDownLight(vec3 light)
 105.352 +{
 105.353 +	return (light / vec3(scene_light_strength, scene_light_strength, scene_light_strength));
 105.354 +}
 105.355 +
 105.356 +vec3 scaleUpLight(vec3 light)
 105.357 +{
 105.358 +	return (light * vec3(scene_light_strength, scene_light_strength, scene_light_strength));
 105.359 +}
 105.360 +
 105.361 +vec3 atmosAmbient(vec3 light)
 105.362 +{
 105.363 +	return getAmblitColor() + (light * vec3(0.5f, 0.5f, 0.5f));
 105.364 +}
 105.365 +
 105.366 +vec3 atmosAffectDirectionalLight(float lightIntensity)
 105.367 +{
 105.368 +	return getSunlitColor() * vec3(lightIntensity, lightIntensity, lightIntensity);
 105.369 +}
 105.370 +
 105.371 +vec3 scaleSoftClip(vec3 light)
 105.372 +{
 105.373 +	//soft clip effect:
 105.374 +    vec3 zeroes = vec3(0.0f, 0.0f, 0.0f);
 105.375 +    vec3 ones   = vec3(1.0f, 1.0f, 1.0f);
 105.376 +
 105.377 +	light = ones - clamp(light, zeroes, ones);
 105.378 +	light = ones - pow(light, gamma.xxx);
 105.379 +
 105.380 +	return light;
 105.381 +}
 105.382 +
 105.383 +vec3 fullbrightAtmosTransport(vec3 light) {
 105.384 +	float brightness = dot(light.rgb, vec3(0.33333));
 105.385 +
 105.386 +	return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
 105.387 +}
 105.388 +
 105.389 +vec3 fullbrightScaleSoftClip(vec3 light)
 105.390 +{
 105.391 +	//soft clip effect:
 105.392 +	return light;
 105.393 +}
 105.394 +
 105.395 +#else
 105.396 +#ifdef DEFINE_GL_FRAGCOLOR
 105.397 +out vec4 frag_data[3];
 105.398 +#else
 105.399 +#define frag_data gl_FragData
 105.400 +#endif
 105.401 +#endif
 105.402 +
 105.403 +uniform sampler2D diffuseMap;
 105.404 +
 105.405 +#if HAS_NORMAL_MAP
 105.406 +uniform sampler2D bumpMap;
 105.407 +#endif
 105.408 +
 105.409 +#if HAS_SPECULAR_MAP
 105.410 +uniform sampler2D specularMap;
 105.411 +
 105.412 +VARYING vec2 vary_texcoord2;
 105.413 +#endif
 105.414 +
 105.415 +uniform float env_intensity;
 105.416 +uniform vec4 specular_color;  // specular color RGB and specular exponent (glossiness) in alpha
 105.417 +
 105.418 +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
 105.419 +uniform float minimum_alpha;
 105.420 +#endif
 105.421 +
 105.422 +#if HAS_NORMAL_MAP
 105.423 +VARYING vec3 vary_mat0;
 105.424 +VARYING vec3 vary_mat1;
 105.425 +VARYING vec3 vary_mat2;
 105.426 +VARYING vec2 vary_texcoord1;
 105.427 +#else
 105.428 +VARYING vec3 vary_normal;
 105.429 +#endif
 105.430 +
 105.431 +VARYING vec4 vertex_color;
 105.432 +VARYING vec2 vary_texcoord0;
 105.433 +
 105.434 +#ifdef SINGLE_FP_ONLY
 105.435 +vec2 encode_normal(vec3 n)
 105.436 +{
 105.437 +	vec2 sn;
 105.438 +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
 105.439 +	return sn;
 105.440 +}
 105.441 +
 105.442 +vec3 decode_normal (vec2 enc)
 105.443 +{
 105.444 +	vec3 n;
 105.445 +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
 105.446 +	n.z = sqrt(1.0f - dot(n.xy,n.xy));
 105.447 +	return n;
 105.448 +}
 105.449 +#else
 105.450 +vec2 encode_normal(vec3 n)
 105.451 +{
 105.452 +	float f = sqrt(8 * n.z + 8);
 105.453 +	return n.xy / f + 0.5;
 105.454 +}
 105.455 +
 105.456 +vec3 decode_normal (vec2 enc)
 105.457 +{
 105.458 +    vec2 fenc = enc*4-2;
 105.459 +    float f = dot(fenc,fenc);
 105.460 +    float g = sqrt(1-f/4);
 105.461 +    vec3 n;
 105.462 +    n.xy = fenc*g;
 105.463 +    n.z = 1-f/2;
 105.464 +    return n;
 105.465 +}
 105.466 +#endif
 105.467 +
 105.468 +void main() 
 105.469 +{
 105.470 +	vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
 105.471 +	diffcol.rgb *= vertex_color.rgb;
 105.472 +
 105.473 +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
 105.474 +	if (diffcol.a < minimum_alpha)
 105.475 +	{
 105.476 +		discard;
 105.477 +	}
 105.478 +#endif
 105.479 +
 105.480 +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
 105.481 +	vec3 old_diffcol = diffcol.rgb;
 105.482 +	diffcol.rgb = pow(diffcol.rgb, vec3(2.2));
 105.483 +#endif
 105.484 +
 105.485 +#if HAS_SPECULAR_MAP
 105.486 +	vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
 105.487 +	spec.rgb *= specular_color.rgb;
 105.488 +#else
 105.489 +	vec4 spec = vec4(specular_color.rgb, 1.0);
 105.490 +#endif
 105.491 +
 105.492 +#if HAS_NORMAL_MAP
 105.493 +	vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
 105.494 +
 105.495 +	norm.xyz = norm.xyz * 2 - 1;
 105.496 +
 105.497 +	vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
 105.498 +			  dot(norm.xyz,vary_mat1),
 105.499 +			  dot(norm.xyz,vary_mat2));
 105.500 +#else
 105.501 +	vec4 norm = vec4(0,0,0,1.0);
 105.502 +	vec3 tnorm = vary_normal;
 105.503 +#endif
 105.504 +
 105.505 +    norm.xyz = tnorm;
 105.506 +    norm.xyz = normalize(norm.xyz);
 105.507 +
 105.508 +	vec4 final_color = diffcol;
 105.509 +	
 105.510 +#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
 105.511 +	final_color.a = emissive_brightness;
 105.512 +#else
 105.513 +	final_color.a = max(final_color.a, emissive_brightness);
 105.514 +#endif
 105.515 +
 105.516 +	vec4 final_specular = spec;
 105.517 +#if HAS_SPECULAR_MAP
 105.518 +	vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0);
 105.519 +	final_specular.a = specular_color.a * norm.a;
 105.520 +#else
 105.521 +	vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0);
 105.522 +	final_specular.a = specular_color.a;
 105.523 +#endif
 105.524 +	
 105.525 +
 105.526 +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
 105.527 +		//forward rendering, output just lit RGBA
 105.528 +	vec3 pos = vary_position;
 105.529 +
 105.530 +#if HAS_SUN_SHADOW
 105.531 +	float shadow = 0.0;
 105.532 +	
 105.533 +	vec4 spos = vec4(pos,1.0);
 105.534 +		
 105.535 +	if (spos.z > -shadow_clip.w)
 105.536 +	{	
 105.537 +		vec4 lpos;
 105.538 +		
 105.539 +		vec4 near_split = shadow_clip*-0.75;
 105.540 +		vec4 far_split = shadow_clip*-1.25;
 105.541 +		vec4 transition_domain = near_split-far_split;
 105.542 +		float weight = 0.0;
 105.543 +
 105.544 +		if (spos.z < near_split.z)
 105.545 +		{
 105.546 +			lpos = shadow_matrix[3]*spos;
 105.547 +			
 105.548 +			float w = 1.0;
 105.549 +			w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
 105.550 +			shadow += pcfShadow(shadowMap3, lpos)*w;
 105.551 +			weight += w;
 105.552 +			shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
 105.553 +		}
 105.554 +
 105.555 +		if (spos.z < near_split.y && spos.z > far_split.z)
 105.556 +		{
 105.557 +			lpos = shadow_matrix[2]*spos;
 105.558 +			
 105.559 +			float w = 1.0;
 105.560 +			w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
 105.561 +			w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
 105.562 +			shadow += pcfShadow(shadowMap2, lpos)*w;
 105.563 +			weight += w;
 105.564 +		}
 105.565 +
 105.566 +		if (spos.z < near_split.x && spos.z > far_split.y)
 105.567 +		{
 105.568 +			lpos = shadow_matrix[1]*spos;
 105.569 +			
 105.570 +			float w = 1.0;
 105.571 +			w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
 105.572 +			w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
 105.573 +			shadow += pcfShadow(shadowMap1, lpos)*w;
 105.574 +			weight += w;
 105.575 +		}
 105.576 +
 105.577 +		if (spos.z > far_split.x)
 105.578 +		{
 105.579 +			lpos = shadow_matrix[0]*spos;
 105.580 +							
 105.581 +			float w = 1.0;
 105.582 +			w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
 105.583 +				
 105.584 +			shadow += pcfShadow(shadowMap0, lpos)*w;
 105.585 +			weight += w;
 105.586 +		}
 105.587 +		
 105.588 +
 105.589 +		shadow /= weight;
 105.590 +	}
 105.591 +	else
 105.592 +	{
 105.593 +		shadow = 1.0;
 105.594 +	}
 105.595 +#else
 105.596 +	float shadow = 1.0;
 105.597 +#endif
 105.598 +
 105.599 +	spec = final_specular;
 105.600 +	vec4 diffuse = final_color;
 105.601 +	float envIntensity = final_normal.z;
 105.602 +
 105.603 +    vec3 col = vec3(0.0f,0.0f,0.0f);
 105.604 +
 105.605 +	float bloom = 0.0;
 105.606 +	calcAtmospherics(pos.xyz, 1.0);
 105.607 +	
 105.608 +	vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
 105.609 +
 105.610 +	float da =dot(norm.xyz, sun_dir.xyz);
 105.611 +    float final_da = da;
 105.612 +          final_da = min(final_da, shadow);
 105.613 +          final_da = max(final_da, diffuse.a);
 105.614 +          final_da = max(final_da, 0.0f);
 105.615 +
 105.616 +	col.rgb = atmosAmbient(col);
 105.617 +	
 105.618 +	float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
 105.619 +	ambient *= 0.5;
 105.620 +	ambient *= ambient;
 105.621 +	ambient = (1.0-ambient);
 105.622 +
 105.623 +	col.rgb *= ambient;
 105.624 +
 105.625 +	col.rgb = col.rgb + atmosAffectDirectionalLight(pow(final_da, 1.0/1.3));
 105.626 +	col.rgb *= old_diffcol.rgb;
 105.627 +	
 105.628 +
 105.629 +	float glare = 0.0;
 105.630 +
 105.631 +	if (spec.a > 0.0) // specular reflection
 105.632 +	{
 105.633 +		// the old infinite-sky shiny reflection
 105.634 +		//
 105.635 +				
 105.636 +		float sa = dot(refnormpersp, sun_dir.xyz);
 105.637 +		vec3 dumbshiny = vary_SunlitColor*shadow*(texture2D(lightFunc, vec2(sa, spec.a)).r);
 105.638 +							
 105.639 +		// add the two types of shiny together
 105.640 +		vec3 spec_contrib = dumbshiny * spec.rgb;
 105.641 +		bloom = dot(spec_contrib, spec_contrib) / 6;
 105.642 +
 105.643 +		glare = max(spec_contrib.r, spec_contrib.g);
 105.644 +		glare = max(glare, spec_contrib.b);
 105.645 +
 105.646 +		col += spec_contrib;
 105.647 +	}
 105.648 +
 105.649 +	col = mix(col.rgb, old_diffcol.rgb, diffuse.a);
 105.650 +
 105.651 +	if (envIntensity > 0.0)
 105.652 +	{
 105.653 +		//add environmentmap
 105.654 +		vec3 env_vec = env_mat * refnormpersp;
 105.655 +		
 105.656 +		vec3 refcol = textureCube(environmentMap, env_vec).rgb;
 105.657 +
 105.658 +		col = mix(col.rgb, refcol, 
 105.659 +			envIntensity);  
 105.660 +
 105.661 +		float cur_glare = max(refcol.r, refcol.g);
 105.662 +		cur_glare = max(cur_glare, refcol.b);
 105.663 +		cur_glare *= envIntensity*4.0;
 105.664 +		glare += cur_glare;
 105.665 +	}
 105.666 +
 105.667 +	col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
 105.668 +	col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
 105.669 +
 105.670 +	//convert to linear space before adding local lights
 105.671 +	col = pow(col, vec3(2.2));
 105.672 +
 105.673 +			
 105.674 +	vec3 npos = normalize(-pos.xyz);
 105.675 +
 105.676 + #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);
 105.677 +
 105.678 +		LIGHT_LOOP(1)
 105.679 +		LIGHT_LOOP(2)
 105.680 +		LIGHT_LOOP(3)
 105.681 +		LIGHT_LOOP(4)
 105.682 +		LIGHT_LOOP(5)
 105.683 +		LIGHT_LOOP(6)
 105.684 +		LIGHT_LOOP(7)
 105.685 +
 105.686 +
 105.687 +	//convert to gamma space for display on screen
 105.688 +	col.rgb = pow(col.rgb, vec3(1.0/2.2));
 105.689 +
 105.690 +	frag_color.rgb = col.rgb;
 105.691 +	glare = min(glare, 1.0);
 105.692 +	frag_color.a = max(diffcol.a,glare)*vertex_color.a;
 105.693 +
 105.694 +#else
 105.695 +	frag_data[0] = final_color;
 105.696 +	frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
 105.697 +	frag_data[2] = final_normal; // XY = Normal.  Z = Env. intensity.
 105.698 +#endif
 105.699 +}
   106.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   106.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl	Thu Jul 18 18:43:58 2013 -0400
   106.3 @@ -0,0 +1,144 @@
   106.4 +/** 
   106.5 + * @file bumpV.glsl
   106.6 + *
   106.7 + * $LicenseInfo:firstyear=2007&license=viewerlgpl$
   106.8 + * Second Life Viewer Source Code
   106.9 + * Copyright (C) 2007, Linden Research, Inc.
  106.10 + * 
  106.11 + * This library is free software; you can redistribute it and/or
  106.12 + * modify it under the terms of the GNU Lesser General Public
  106.13 + * License as published by the Free Software Foundation;
  106.14 + * version 2.1 of the License only.
  106.15 + * 
  106.16 + * This library is distributed in the hope that it will be useful,
  106.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  106.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  106.19 + * Lesser General Public License for more details.
  106.20 + * 
  106.21 + * You should have received a copy of the GNU Lesser General Public
  106.22 + * License along with this library; if not, write to the Free Software
  106.23 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  106.24 + * 
  106.25 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  106.26 + * $/LicenseInfo$
  106.27 + */
  106.28 +
  106.29 +#define DIFFUSE_ALPHA_MODE_IGNORE 0
  106.30 +#define DIFFUSE_ALPHA_MODE_BLEND 1
  106.31 +#define DIFFUSE_ALPHA_MODE_MASK 2
  106.32 +#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
  106.33 +
  106.34 +#if HAS_SKIN
  106.35 +uniform mat4 modelview_matrix;
  106.36 +uniform mat4 projection_matrix;
  106.37 +mat4 getObjectSkinnedTransform();
  106.38 +#else
  106.39 +uniform mat3 normal_matrix;
  106.40 +uniform mat4 modelview_projection_matrix;
  106.41 +#endif
  106.42 +
  106.43 +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
  106.44 +
  106.45 +#if !HAS_SKIN
  106.46 +uniform mat4 modelview_matrix;
  106.47 +#endif
  106.48 +
  106.49 +VARYING vec3 vary_position;
  106.50 +
  106.51 +#endif
  106.52 +
  106.53 +uniform mat4 texture_matrix0;
  106.54 +
  106.55 +ATTRIBUTE vec3 position;
  106.56 +ATTRIBUTE vec4 diffuse_color;
  106.57 +ATTRIBUTE vec3 normal;
  106.58 +ATTRIBUTE vec2 texcoord0;
  106.59 +
  106.60 +
  106.61 +#if HAS_NORMAL_MAP
  106.62 +ATTRIBUTE vec4 tangent;
  106.63 +ATTRIBUTE vec2 texcoord1;
  106.64 +
  106.65 +VARYING vec3 vary_mat0;
  106.66 +VARYING vec3 vary_mat1;
  106.67 +VARYING vec3 vary_mat2;
  106.68 +
  106.69 +VARYING vec2 vary_texcoord1;
  106.70 +#else
  106.71 +VARYING vec3 vary_normal;
  106.72 +#endif
  106.73 +
  106.74 +#if HAS_SPECULAR_MAP
  106.75 +ATTRIBUTE vec2 texcoord2;
  106.76 +VARYING vec2 vary_texcoord2;
  106.77 +#endif
  106.78 + 
  106.79 +VARYING vec4 vertex_color;
  106.80 +VARYING vec2 vary_texcoord0;
  106.81 +
  106.82 +void main()
  106.83 +{
  106.84 +#if HAS_SKIN
  106.85 +	mat4 mat = getObjectSkinnedTransform();
  106.86 +
  106.87 +	mat = modelview_matrix * mat;
  106.88 +
  106.89 +	vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
  106.90 +
  106.91 +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
  106.92 +	vary_position = pos;
  106.93 +#endif
  106.94 +
  106.95 +	gl_Position = projection_matrix*vec4(pos,1.0);
  106.96 +
  106.97 +#else
  106.98 +	//transform vertex
  106.99 +	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); 
 106.100 +
 106.101 +#endif
 106.102 +	
 106.103 +	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 106.104 +	
 106.105 +#if HAS_NORMAL_MAP
 106.106 +	vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
 106.107 +#endif
 106.108 +
 106.109 +#if HAS_SPECULAR_MAP
 106.110 +	vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy;
 106.111 +#endif
 106.112 +
 106.113 +#if HAS_SKIN
 106.114 +	vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
 106.115 +#if HAS_NORMAL_MAP
 106.116 +	vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz);
 106.117 +	vec3 b = cross(n, t)*tangent.w;
 106.118 +	
 106.119 +	vary_mat0 = vec3(t.x, b.x, n.x);
 106.120 +	vary_mat1 = vec3(t.y, b.y, n.y);
 106.121 +	vary_mat2 = vec3(t.z, b.z, n.z);
 106.122 +#else //HAS_NORMAL_MAP
 106.123 +vary_normal  = n;
 106.124 +#endif //HAS_NORMAL_MAP
 106.125 +#else //HAS_SKIN
 106.126 +	vec3 n = normalize(normal_matrix * normal);
 106.127 +#if HAS_NORMAL_MAP
 106.128 +	vec3 t = normalize(normal_matrix * tangent.xyz);
 106.129 +	vec3 b = cross(n,t)*tangent.w;
 106.130 +	//vec3 t = cross(b,n) * binormal.w;
 106.131 +	
 106.132 +	vary_mat0 = vec3(t.x, b.x, n.x);
 106.133 +	vary_mat1 = vec3(t.y, b.y, n.y);
 106.134 +	vary_mat2 = vec3(t.z, b.z, n.z);
 106.135 +#else //HAS_NORMAL_MAP
 106.136 +	vary_normal = n;
 106.137 +#endif //HAS_NORMAL_MAP
 106.138 +#endif //HAS_SKIN
 106.139 +	
 106.140 +	vertex_color = diffuse_color;
 106.141 +
 106.142 +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
 106.143 +#if !HAS_SKIN
 106.144 +	vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
 106.145 +#endif
 106.146 +#endif
 106.147 +}
   107.1 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl	Thu Jul 18 15:14:55 2013 -0400
   107.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl	Thu Jul 18 18:43:58 2013 -0400
   107.3 @@ -56,6 +56,40 @@
   107.4  
   107.5  uniform mat4 inv_proj;
   107.6  
   107.7 +#ifdef SINGLE_FP_ONLY
   107.8 +vec2 encode_normal(vec3 n)
   107.9 +{
  107.10 +	vec2 sn;
  107.11 +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
  107.12 +	return sn;
  107.13 +}
  107.14 +
  107.15 +vec3 decode_normal (vec2 enc)
  107.16 +{
  107.17 +	vec3 n;
  107.18 +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
  107.19 +	n.z = sqrt(1.0f - dot(n.xy,n.xy));
  107.20 +	return n;
  107.21 +}
  107.22 +#else
  107.23 +vec2 encode_normal(vec3 n)
  107.24 +{
  107.25 +	float f = sqrt(8 * n.z + 8);
  107.26 +	return n.xy / f + 0.5;
  107.27 +}
  107.28 +
  107.29 +vec3 decode_normal (vec2 enc)
  107.30 +{
  107.31 +    vec2 fenc = enc*4-2;
  107.32 +    float f = dot(fenc,fenc);
  107.33 +    float g = sqrt(1-f/4);
  107.34 +    vec3 n;
  107.35 +    n.xy = fenc*g;
  107.36 +    n.z = 1-f/2;
  107.37 +    return n;
  107.38 +}
  107.39 +#endif
  107.40 +
  107.41  vec4 getPosition(vec2 pos_screen)
  107.42  {
  107.43  	float depth = texture2DRect(depthMap, pos_screen.xy).r;
  107.44 @@ -79,7 +113,7 @@
  107.45  	}
  107.46  	
  107.47  	vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
  107.48 -	norm = (norm.xyz-0.5)*2.0; // unpack norm
  107.49 +	norm = decode_normal(norm.xy); // unpack norm
  107.50  	norm = normalize(norm);
  107.51  	vec4 spec = texture2DRect(specularRect, frag.xy);
  107.52  	vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;
  107.53 @@ -93,9 +127,9 @@
  107.54  		bool light_contrib = (i < light_count);
  107.55  		
  107.56  		vec3 lv = light[i].xyz-pos;
  107.57 -		float dist2 = dot(lv,lv);
  107.58 -		dist2 /= light[i].w;
  107.59 -		if (dist2 > 1.0)
  107.60 +		float dist = length(lv);
  107.61 +		dist /= light[i].w;
  107.62 +		if (dist > 1.0)
  107.63  		{
  107.64  			light_contrib = false;
  107.65  		}
  107.66 @@ -110,27 +144,39 @@
  107.67  		{
  107.68  			lv = normalize(lv);
  107.69  			da = dot(norm, lv);
  107.70 -					
  107.71 +			
  107.72  			float fa = light_col[i].a+1.0;
  107.73 -			float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
  107.74 +			float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
  107.75 +			dist_atten *= dist_atten;
  107.76 +			dist_atten *= 2.0;
  107.77 +			
  107.78  			dist_atten *= noise;
  107.79  
  107.80  			float lit = da * dist_atten;
  107.81 +						
  107.82 +			vec3 col = light_col[i].rgb*lit*diff;
  107.83  			
  107.84 -			vec3 col = light_col[i].rgb*lit*diff;
  107.85  			//vec3 col = vec3(dist2, light_col[i].a, lit);
  107.86  			
  107.87  			if (spec.a > 0.0)
  107.88  			{
  107.89 +				lit = min(da*6.0, 1.0) * dist_atten;
  107.90  				//vec3 ref = dot(pos+lv, norm);
  107.91 -				
  107.92 -				float sa = dot(normalize(lv+npos),norm);
  107.93 -				
  107.94 -				if (sa > 0.0)
  107.95 +				vec3 h = normalize(lv+npos);
  107.96 +				float nh = dot(norm, h);
  107.97 +				float nv = dot(norm, npos);
  107.98 +				float vh = dot(npos, h);
  107.99 +				float sa = nh;
 107.100 +				float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
 107.101 +
 107.102 +				float gtdenom = 2 * nh;
 107.103 +				float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
 107.104 +								
 107.105 +				if (nh > 0.0)
 107.106  				{
 107.107 -					sa = 6 * texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0);
 107.108 -					sa *= noise;
 107.109 -					col += da*sa*light_col[i].rgb*spec.rgb;
 107.110 +					float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
 107.111 +					col += lit*scol*light_col[i].rgb*spec.rgb;
 107.112 +					//col += spec.rgb;
 107.113  				}
 107.114  			}
 107.115  			
   108.1 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl	Thu Jul 18 15:14:55 2013 -0400
   108.2 +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl	Thu Jul 18 18:43:58 2013 -0400
   108.3 @@ -40,6 +40,7 @@
   108.4  uniform samplerCube environmentMap;
   108.5  uniform sampler2D noiseMap;
   108.6  uniform sampler2D projectionMap;
   108.7 +uniform sampler2D lightFunc;
   108.8  
   108.9  uniform mat4 proj_mat; //screen space to light space
  108.10  uniform float proj_near; //near clip for projection
  108.11 @@ -66,9 +67,49 @@
  108.12  
  108.13  uniform mat4 inv_proj;
  108.14  
  108.15 +#ifdef SINGLE_FP_ONLY
  108.16 +vec2 encode_normal(vec3 n)
  108.17 +{
  108.18 +	vec2 sn;
  108.19 +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
  108.20 +	return sn;
  108.21 +}
  108.22 +
  108.23 +vec3 decode_normal (vec2 enc)
  108.24 +{
  108.25 +	vec3 n;
  108.26 +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
  108.27 +	n.z = sqrt(1.0f - dot(n.xy,n.xy));
  108.28 +	return n;
  108.29 +}
  108.30 +#else
  108.31 +vec2 encode_normal(vec3 n)
  108.32 +{
  108.33 +	float f = sqrt(8 * n.z + 8);
  108.34 +	return n.xy / f + 0.5;
  108.35 +}
  108.36 +
  108.37 +vec3 decode_normal (vec2 enc)
  108.38 +{
  108.39 +    vec2 fenc = enc*4-2;
  108.40 +    float f = dot(fenc,fenc);
  108.41 +    float g = sqrt(1-f/4);
  108.42 +    vec3 n;
  108.43 +    n.xy = fenc*g;
  108.44 +    n.z = 1-f/2;
  108.45 +    return n;
  108.46 +}
  108.47 +#endif
  108.48 +
  108.49 +vec4 correctWithGamma(vec4 col)
  108.50 +{
  108.51 +	return vec4(pow(col.rgb, vec3(2.2)), col.a);
  108.52 +}
  108.53 +
  108.54  vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
  108.55  {
  108.56  	vec4 ret = texture2DLod(projectionMap, tc, lod);
  108.57 +	ret = correctWithGamma(ret);