Automated merge with ssh://hg.lindenlab.com/richard/viewer-experience

master
Richard Linden 2011-06-23 11:35:14 -07:00
commit af142618f9
979 changed files with 28555 additions and 13728 deletions

32
.hgtags
View File

@ -72,7 +72,6 @@ b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-beta3
b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-34_2.5.0-beta3
b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-release
b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-31_2.5.0-release
92e58e51776a4f8c29069b1a62ff21454d2085f0 2.6.0-start
3178e311da3a8739a85363665006ea3c4610cad4 dons-headless-hackathon-work
63a6aedfce785a6c760377bf685b2dae616797d2 2.5.1-start
4dede9ae1ec74d41f6887719f6f1de7340d8578d 2.5.1-release
@ -81,7 +80,6 @@ b53a0576eec80614d7767ed72b40ed67aeff27c9 DRTVWR-38_2.5.2-release
b53a0576eec80614d7767ed72b40ed67aeff27c9 2.5.2-release
92e58e51776a4f8c29069b1a62ff21454d2085f0 2.6.0-start
f1827b441e05bf37c68e2c15ebc6d09e9b03f527 2.6.0-start
f1827b441e05bf37c68e2c15ebc6d09e9b03f527 2.6.0-start
4e9eec6a347f89b2b3f295beb72f1cf7837dff66 2.6.0-start
9283d6d1d7eb71dfe4c330e7c9144857e7356bde 2.6.0-beta1
9283d6d1d7eb71dfe4c330e7c9144857e7356bde DRTVWR-40_2.6.0-beta1
@ -114,12 +112,7 @@ bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 2.6.6-beta1
beafa8a9bd1d1b670b7523d865204dc4a4b38eef DRTVWR-55_2.6.8-beta1
beafa8a9bd1d1b670b7523d865204dc4a4b38eef 2.6.8-beta1
11d5d8080e67c3955914caf98f2eb116af30e55a 2.6.9-start
11d5d8080e67c3955914caf98f2eb116af30e55a 2.6.9-start
beafa8a9bd1d1b670b7523d865204dc4a4b38eef DRTVWR-55_2.6.8-beta1
beafa8a9bd1d1b670b7523d865204dc4a4b38eef 2.6.8-beta1
e67da2c6e3125966dd49eef98b36317afac1fcfe 2.6.9-start
beafa8a9bd1d1b670b7523d865204dc4a4b38eef DRTVWR-55_2.6.8-beta1
beafa8a9bd1d1b670b7523d865204dc4a4b38eef 2.6.8-beta1
77e5a08344c95738ab879f9671b7758cddd712a3 DRTVWR-57_2.6.9-beta1
77e5a08344c95738ab879f9671b7758cddd712a3 2.6.9-beta1
be2000b946f8cb3de5f44b2d419287d4c48ec4eb DRTVWR-54_2.6.8-release
@ -130,13 +123,22 @@ dac76a711da5f1489a01c1fa62ec97d99c25736d 2.6.6-release
8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release
77e5a08344c95738ab879f9671b7758cddd712a3 DRTVWR-56_2.6.9-release
8835e0e3c0d3a48244c287bc05811dfc2fba43ec 2.7.0-start
77e5a08344c95738ab879f9671b7758cddd712a3 2.6.9-release
54fd44ac92e4c61435ea33effe093a3527e18d98 2.7.1-start
be2000b946f8cb3de5f44b2d419287d4c48ec4eb DRTVWR-54_2.6.8-release
be2000b946f8cb3de5f44b2d419287d4c48ec4eb 2.6.8-release
dac76a711da5f1489a01c1fa62ec97d99c25736d DRTVWR-51_2.6.6-release
dac76a711da5f1489a01c1fa62ec97d99c25736d 2.6.6-release
8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release
8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release
43c7ee846b7eed80786acbbf35d03bd016a3e85d DRTVWR-59_2.7.0-beta1
43c7ee846b7eed80786acbbf35d03bd016a3e85d 2.7.0-beta1
77e5a08344c95738ab879f9671b7758cddd712a3 2.6.9-release
54fd44ac92e4c61435ea33effe093a3527e18d98 2.7.1-start
0c4d0c24278074f219e5a32e72b449e78301d11b DRTVWR-61_2.7.1-beta1
0c4d0c24278074f219e5a32e72b449e78301d11b 2.7.1-beta1
8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release
8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release
77e5a08344c95738ab879f9671b7758cddd712a3 DRTVWR-56_2.6.9-release
9f79a6ed8fdcd2f3dac33ea6b3236eeb278dccfe 2.7.2-start
e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb DRTVWR-63_2.7.2-beta1
e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb 2.7.2-beta1
6a3e7e403bd19e45fdfc2fcc716867af3ab80861 2.7.3-start
6af10678de4736222b2c3f7e010e984fb5b327de 2.7.4-start
77e5a08344c95738ab879f9671b7758cddd712a3 2.6.9-release
a9abb9633a266c8d2fe62411cfd1c86d32da72bf DRTVWR-60_2.7.1-release
a9abb9633a266c8d2fe62411cfd1c86d32da72bf 2.7.1-release
e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb DRTVWR-63_2.7.2-beta1
e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb 2.7.2-beta1

View File

@ -69,29 +69,9 @@ viewer-pre-release.viewer_channel = "Second Life Release"
viewer-pre-release.login_channel = "Second Life Release"
viewer-pre-release.build_debug_release_separately = true
viewer-pre-release.build_viewer_update_version_manager = true
#viewer-pre-release.release-viewer.jira = DRTVWR-13
viewer-pre-release.release-viewer.jira = DRTVWR-46
#viewer-pre-release.release-viewer.jira = DRTVWR-46
# =======================================
# brad
# ========================================
debug-halting.email = cg@lindenlab.com
debug-halting.build_server = false
debug-halting.build_server_tests = false
debug-halting.build_Darwin = false
debug-halting.build_Linux = false
debug-halting.build_CYGWIN_Debug = false
debug-halting.build_CYGWIN_RelWithDebInfo = false
# ========================================
# brad
# ========================================
brad-parabuild.email = brad@lindenlab.com
brad-parabuild.build_server = false
brad-parabuild.build_server_tests = false
# ========================================
# mesh-development
# ========================================
@ -102,6 +82,16 @@ mesh-development.build_debug_release_separately = true
mesh-development.build_CYGWIN_Debug = false
mesh-development.build_viewer_update_version_manager = false
# ========================================
# mesh-asset-deprecation
# ========================================
mesh-asset-deprecation.viewer_channel = "Project Viewer - Mesh Asset Deprecation"
mesh-asset-deprecation.login_channel = "Project Viewer - Mesh Asset Deprecation"
mesh-asset-deprecation.viewer_grid = aditi
mesh-asset-deprecation.build_debug_release_separately = true
mesh-asset-deprecation.build_CYGWIN_Debug = false
mesh-asset-deprecation.build_viewer_update_version_manager = false
# ========================================
# viewer-mesh
# ========================================
@ -123,71 +113,30 @@ viewer-mesh.email = shining@lists.lindenlab.com
# CG
# ========================================
cg_viewer-development_lenny.collect_metrics = true
cg_viewer-development_lenny.show_changes_since = 4b140ce7839d
cg_viewer-development_lenny.email = cg@lindenlab.com
# ========================================
# gooey
# ========================================
#gooey.email = james@lindenlab.com
gooey.build_Debug = false
gooey.build_RelWithDebInfo = false
gooey.build_server = false
gooey.build_server_tests = false
gooey.viewer_channel = "Second Life Alpha"
gooey.login_channel = "Second Life Alpha"
gooey.viewer_grid = agni
gooey.build_viewer_update_version_manager = false
# ========================================
# Search Project
# ========================================
search_project-viewer.build_debug_release_separately = true
search_project-viewer.viewer_channel = "Second Life Project Viewer - Search"
search_project-viewer.login_channel = "Second Life Project Viewer - Search"
# ========================================
# palange
# ========================================
palange_viewer-2-0.email = palange@lindenlab.com
palange_viewer-2-0.build_server = false
palange_viewer-2-0.build_server_tests = false
palange_viewer-2-0.build_CYGWIN_Debug = false
# ========================================
# media
# ========================================
media.email = skolb@lindenlab.com
media.build_server = false
media.build_server_tests = false
media.viewer_channel = "Second Life Alpha"
media.login_channel = "Second Life Alpha"
media.viewer_grid = agni
media.build_viewer_update_version_manager = false
# ================
# oz
# ================
oz_viewer-devreview.build_debug_release_separately = true
oz_project-1.build_debug_release_separately = true
oz_project-2.build_debug_release_separately = true
oz-project-3.build_debug_release_separately = true
oz_viewer-devreview.codeticket_add_context = false
oz_project-1.build_debug_release_separately = true
oz_project-1.codeticket_add_context = false
oz_project-2.build_debug_release_separately = true
oz_project-2.codeticket_add_context = false
oz_project-3.build_debug_release_separately = true
oz_project-3.codeticket_add_context = false
oz_project-4.build_debug_release_separately = true
oz_project-4.codeticket_add_context = false
oz_viewer-beta-review.build_debug_release_separately = true
# ========================================
# enus
# ========================================
oz_viewer-beta-review.codeticket_add_context = false
viewer-tut-teamcity.email = enus@lindenlab.com
viewer-tut-teamcity.build_server = false
viewer-tut-teamcity.build_server_tests = false
oz_viewer-poreview.build_debug_release_separately = true
oz_viewer-poreview.codeticket_add_context = false
# =================================================================
# asset delivery 2010 projects
@ -206,23 +155,4 @@ viewer-asset-delivery-metrics.email = monty@lindenlab.com
viewer-asset-delivery-metrics.build_server = false
viewer-asset-delivery-metrics.build_server_tests = false
#==============================================================================
# autobuild viewers
#==============================================================================
viewer-autobuild2010.build_debug_release_separately = true
viewer-autobuild2010.viewer_channel = "Project Viewer - VS2010"
viewer-autobuild2010.login_channel = "Project Viewer - VS2010"
viewer-autobuild2010.viewer_grid = agni
viewer-autobuild2010.build_link_parallel = false
#========================================
# VS2010
#========================================
viewer-vs2010.viewer_channel = "Project Viewer - VS2010"
viewer-vs2010.login_channel = "Project Viewer - VS2010"
viewer-vs2010.viewer_grid = agni
viewer-vs2010.build_debug_release_separately = true
viewer-vs2010.build_viewer_update_version_manager = false
viewer-vs2010.build_link_parallel = false
# eof

View File

@ -18,9 +18,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>930bdd987a321eda1838caba8cd6098f</string>
<string>b2fe1c860613a68e74d4384be418ffee</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/230348/arch/Darwin/installer/glod-1.0pre4-darwin-20110519.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/232684/arch/Darwin/installer/glod-1.0pre4-darwin-20110610.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@ -30,9 +30,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>fb33b6cac2e6b98f93c5efa2af2e5a00</string>
<string>c0c64dae149d0892343e2ff300fd06b9</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/230348/arch/Linux/installer/glod-1.0pre4-linux-20110519.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/232684/arch/Linux/installer/glod-1.0pre4-linux-20110611.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -42,9 +42,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>388cf0e292f756b4bb37696622f0bbc5</string>
<string>842208365f5b108dac4c7c733b99da9c</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/230348/arch/CYGWIN/installer/glod-1.0pre4-windows-20110519.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/232684/arch/CYGWIN/installer/glod-1.0pre4-windows-20110610.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -1290,9 +1290,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>c81bacf922bb3b540d92b660364c48ce</string>
<string>9bf7a96c1d2fadb180fda91740c945c6</string>
<key>url</key>
<string>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ndofdev-linux-0.2-20101013.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-libndofdev-linux/rev/233137/arch/Linux/installer/libndofdev-0.3-linux-20110617.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -1524,7 +1524,7 @@
<key>hash</key>
<string>bb0abe962b3b8208ed2dab0424aab33d</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-pcre/rev/228822/arch/Linux/installer/pcre-7.6-linux-20110504.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-pcre/rev/228822/arch/Linux/installer/pcre-7.6-linux-20110504.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>

View File

@ -76,6 +76,7 @@ Aleric Inglewood
VWR-13996
VWR-14426
VWR-24247
VWR-25654
VWR-24251
VWR-24252
VWR-24254
@ -209,6 +210,7 @@ Boroondas Gupte
STORM-1182
VWR-233
VWR-20583
VWR-25654
VWR-20891
VWR-23455
VWR-24487
@ -440,6 +442,10 @@ Jonathan Yap
STORM-1095
STORM-1236
STORM-1259
STORM-787
STORM-1313
STORM-899
STORM-1273
Kage Pixel
VWR-11
Ken March
@ -849,6 +855,7 @@ Twisted Laws
STORM-844
STORM-643
STORM-954
STORM-1103
Vadim Bigbear
VWR-2681
Vector Hastings

View File

@ -2,31 +2,25 @@
* @file llaccountingquota.h
* @
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* Copyright (C) 2011, Linden Research, Inc.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@ -35,30 +29,38 @@
struct ParcelQuota
{
ParcelQuota( F32 ownerRenderCost, F32 ownerPhysicsCost, F32 ownerNetworkCost, F32 ownerSimulationCost,
F32 groupRenderCost, F32 groupPhysicsCost, F32 groupNetworkCost, F32 groupSimulationCost,
F32 otherRenderCost, F32 otherPhysicsCost, F32 otherNetworkCost, F32 otherSimulationCost,
F32 totalRenderCost, F32 totalPhysicsCost, F32 totalNetworkCost, F32 totalSimulationCost)
ParcelQuota( F32 ownerRenderCost, F32 ownerPhysicsCost, F32 ownerNetworkCost, F32 ownerSimulationCost,
F32 groupRenderCost, F32 groupPhysicsCost, F32 groupNetworkCost, F32 groupSimulationCost,
F32 otherRenderCost, F32 otherPhysicsCost, F32 otherNetworkCost, F32 otherSimulationCost,
F32 tempRenderCost, F32 tempPhysicsCost, F32 tempNetworkCost, F32 tempSimulationCost,
F32 selectedRenderCost, F32 selectedPhysicsCost, F32 selectedNetworkCost, F32 selectedSimulationCost,
F32 parcelCapacity )
: mOwnerRenderCost( ownerRenderCost ), mOwnerPhysicsCost( ownerPhysicsCost )
, mOwnerNetworkCost( ownerNetworkCost ), mOwnerSimulationCost( ownerSimulationCost )
, mGroupRenderCost( groupRenderCost ), mGroupPhysicsCost( groupPhysicsCost )
, mGroupNetworkCost( groupNetworkCost ), mGroupSimulationCost( groupSimulationCost )
, mOtherRenderCost( otherRenderCost ), mOtherPhysicsCost( otherPhysicsCost )
, mOtherNetworkCost( otherNetworkCost ), mOtherSimulationCost( otherSimulationCost )
, mTotalRenderCost( totalRenderCost ), mTotalPhysicsCost( totalPhysicsCost )
, mTotalNetworkCost( totalNetworkCost ), mTotalSimulationCost( totalSimulationCost )
, mTempRenderCost( tempRenderCost ), mTempPhysicsCost( tempPhysicsCost )
, mTempNetworkCost( tempNetworkCost ), mTempSimulationCost( tempSimulationCost )
, mSelectedRenderCost( tempRenderCost ), mSelectedPhysicsCost( tempPhysicsCost )
, mSelectedNetworkCost( tempNetworkCost ), mSelectedSimulationCost( selectedSimulationCost )
, mParcelCapacity( parcelCapacity )
{
}
ParcelQuota(){}
F32 mOwnerRenderCost, mOwnerPhysicsCost, mOwnerNetworkCost, mOwnerSimulationCost;
F32 mGroupRenderCost, mGroupPhysicsCost, mGroupNetworkCost, mGroupSimulationCost;
F32 mOtherRenderCost, mOtherPhysicsCost, mOtherNetworkCost, mOtherSimulationCost;
F32 mTotalRenderCost, mTotalPhysicsCost, mTotalNetworkCost, mTotalSimulationCost;
F32 mTempRenderCost, mTempPhysicsCost, mTempNetworkCost, mTempSimulationCost;
F32 mSelectedRenderCost, mSelectedPhysicsCost, mSelectedNetworkCost, mSelectedSimulationCost;
F32 mParcelCapacity;
};
struct SelectionQuota
{
SelectionQuota( S32 localId, F32 renderCost, F32 physicsCost, F32 networkCost, F32 simulationCost )
SelectionQuota( LLUUID localId, F32 renderCost, F32 physicsCost, F32 networkCost, F32 simulationCost )
: mLocalId( localId)
, mRenderCost( renderCost )
, mPhysicsCost( physicsCost )
@ -69,7 +71,7 @@ struct SelectionQuota
SelectionQuota() {}
F32 mRenderCost, mPhysicsCost, mNetworkCost, mSimulationCost;
S32 mLocalId;
LLUUID mLocalId;
};
#endif

View File

@ -93,6 +93,7 @@ LLFolderDictionary::LLFolderDictionary()
addEntry(LLFolderType::FT_MESH, new FolderEntry("mesh", TRUE));
addEntry(LLFolderType::FT_INBOX, new FolderEntry("inbox", TRUE));
addEntry(LLFolderType::FT_OUTBOX, new FolderEntry("outbox", TRUE));
addEntry(LLFolderType::FT_NONE, new FolderEntry("-1", FALSE));
};

View File

@ -83,8 +83,9 @@ public:
FT_MESH = 49,
FT_INBOX = 50,
FT_OUTBOX = 51,
FT_COUNT = 51,
FT_COUNT,
FT_NONE = -1
};

View File

@ -2036,7 +2036,9 @@ std::string zip_llsd(LLSD& data)
{ //copy result into output
if (strm.avail_out >= CHUNK)
{
llerrs << "WTF?" << llendl;
free(output);
llwarns << "Failed to compress LLSD block." << llendl;
return std::string();
}
have = CHUNK-strm.avail_out;

View File

@ -737,7 +737,7 @@ void LLPerfBlock::addStatsToLLSDandReset( LLSD & stats,
}
}
else
{ // WTF? Shouldn't have a NULL pointer in the map.
{ // Shouldn't have a NULL pointer in the map.
llwarns << "Unexpected NULL dynamic stat at '" << stats_full_path << "'" << llendl;
}
}

View File

@ -188,22 +188,30 @@ LLOSInfo::LLOSInfo() :
if(osvi.wProductType == VER_NT_WORKSTATION)
mOSStringSimple = "Microsoft Windows XP x64 Edition ";
else
mOSStringSimple = "Microsoft Windows Server 2003 ";
mOSStringSimple = "Microsoft Windows Server 2003 ";
}
else if(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion <= 1)
else if(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion <= 2)
{
if(osvi.dwMinorVersion == 0)
{
mOSStringSimple = "Microsoft Windows Vista ";
if(osvi.wProductType == VER_NT_WORKSTATION)
mOSStringSimple = "Microsoft Windows Vista ";
else
mOSStringSimple = "Windows Server 2008 ";
}
else if(osvi.dwMinorVersion == 1)
{
mOSStringSimple = "Microsoft Windows 7 ";
if(osvi.wProductType == VER_NT_WORKSTATION)
mOSStringSimple = "Microsoft Windows 7 ";
else
mOSStringSimple = "Windows Server 2008 R2 ";
}
if(osvi.wProductType != VER_NT_WORKSTATION)
else if(osvi.dwMinorVersion == 2)
{
mOSStringSimple += "Server ";
if(osvi.wProductType == VER_NT_WORKSTATION)
mOSStringSimple = "Microsoft Windows 8 ";
else
mOSStringSimple = "Windows Server 2012 ";
}
///get native system info if available..
@ -308,8 +316,7 @@ LLOSInfo::LLOSInfo() :
std::string compatibility_mode;
if(got_shell32_version)
{
if(osvi.dwMajorVersion != shell32_major
|| osvi.dwMinorVersion != shell32_minor)
if(osvi.dwMajorVersion != shell32_major || osvi.dwMinorVersion != shell32_minor)
{
compatibility_mode = llformat(" compatibility mode. real ver: %d.%d (Build %d)",
shell32_major,

View File

@ -29,7 +29,7 @@
const S32 LL_VERSION_MAJOR = 2;
const S32 LL_VERSION_MINOR = 7;
const S32 LL_VERSION_PATCH = 2;
const S32 LL_VERSION_PATCH = 5;
const S32 LL_VERSION_BUILD = 0;
const char * const LL_CHANNEL = "Second Life Developer";

View File

@ -35,12 +35,14 @@
#define OCT_ERRS LL_WARNS("OctreeErrors")
#define LL_OCTREE_PARANOIA_CHECK 0
extern U32 gOctreeMaxCapacity;
/*#define LL_OCTREE_PARANOIA_CHECK 0
#if LL_DARWIN
#define LL_OCTREE_MAX_CAPACITY 32
#else
#define LL_OCTREE_MAX_CAPACITY 128
#endif
#endif*/
template <class T> class LLOctreeNode;
@ -74,6 +76,7 @@ template <class T>
class LLOctreeNode : public LLTreeNode<T>
{
public:
typedef LLOctreeTraveler<T> oct_traveler;
typedef LLTreeTraveler<T> tree_traveler;
typedef typename std::set<LLPointer<T> > element_list;
@ -294,8 +297,8 @@ public:
//is it here?
if (isInside(data->getPositionGroup()))
{
if ((getElementCount() < LL_OCTREE_MAX_CAPACITY && contains(data->getBinRadius()) ||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= LL_OCTREE_MAX_CAPACITY)))
if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) ||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
{ //it belongs here
#if LL_OCTREE_PARANOIA_CHECK
//if this is a redundant insertion, error out (should never happen)

View File

@ -100,7 +100,7 @@ void assert_aligned(void* ptr, uintptr_t alignment)
uintptr_t t = (uintptr_t) ptr;
if (t%alignment != 0)
{
llerrs << "WTF?" << llendl;
llerrs << "Alignment check failed." << llendl;
}
#endif
}
@ -361,7 +361,7 @@ public:
}
else
{
llerrs << "WTF? Empty leaf" << llendl;
llerrs << "Empty leaf" << llendl;
}
for (S32 i = 0; i < branch->getChildCount(); ++i)
@ -416,6 +416,70 @@ LLProfile::Face* LLProfile::addFace(S32 i, S32 count, F32 scaleU, S16 faceID, BO
return face;
}
//static
S32 LLProfile::getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset, F32 bevel, F32 ang_scale, S32 split)
{ // this is basically LLProfile::genNGon stripped down to only the operations that influence the number of points
LLMemType m1(LLMemType::MTYPE_VOLUME);
S32 np = 0;
// Generate an n-sided "circular" path.
// 0 is (1,0), and we go counter-clockwise along a circular path from there.
F32 t, t_step, t_first, t_fraction;
F32 begin = params.getBegin();
F32 end = params.getEnd();
t_step = 1.0f / sides;
t_first = floor(begin * sides) / (F32)sides;
// pt1 is the first point on the fractional face.
// Starting t and ang values for the first face
t = t_first;
// Increment to the next point.
// pt2 is the end point on the fractional face
t += t_step;
t_fraction = (begin - t_first)*sides;
// Only use if it's not almost exactly on an edge.
if (t_fraction < 0.9999f)
{
np++;
}
// There's lots of potential here for floating point error to generate unneeded extra points - DJS 04/05/02
while (t < end)
{
// Iterate through all the integer steps of t.
np++;
t += t_step;
}
t_fraction = (end - (t - t_step))*sides;
// Find the fraction that we need to add to the end point.
t_fraction = (end - (t - t_step))*sides;
if (t_fraction > 0.0001f)
{
np++;
}
// If we're sliced, the profile is open.
if ((end - begin)*ang_scale < 0.99f)
{
if (params.getHollow() <= 0)
{
// put center point if not hollow.
np++;
}
}
return np;
}
// What is the bevel parameter used for? - DJS 04/05/02
// Bevel parameter is currently unused but presumedly would support
// filleted and chamfered corners
@ -672,6 +736,117 @@ LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F3
return face;
}
//static
S32 LLProfile::getNumPoints(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split,
BOOL is_sculpted, S32 sculpt_size)
{ // this is basically LLProfile::generate stripped down to only operations that influence the number of points
LLMemType m1(LLMemType::MTYPE_VOLUME);
if (detail < MIN_LOD)
{
detail = MIN_LOD;
}
// Generate the face data
F32 hollow = params.getHollow();
S32 np = 0;
switch (params.getCurveType() & LL_PCODE_PROFILE_MASK)
{
case LL_PCODE_PROFILE_SQUARE:
{
np = getNumNGonPoints(params, 4,-0.375, 0, 1, split);
if (hollow)
{
np *= 2;
}
}
break;
case LL_PCODE_PROFILE_ISOTRI:
case LL_PCODE_PROFILE_RIGHTTRI:
case LL_PCODE_PROFILE_EQUALTRI:
{
np = getNumNGonPoints(params, 3,0, 0, 1, split);
if (hollow)
{
np *= 2;
}
}
break;
case LL_PCODE_PROFILE_CIRCLE:
{
// If this has a square hollow, we should adjust the
// number of faces a bit so that the geometry lines up.
U8 hole_type=0;
F32 circle_detail = MIN_DETAIL_FACES * detail;
if (hollow)
{
hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK;
if (hole_type == LL_PCODE_HOLE_SQUARE)
{
// Snap to the next multiple of four sides,
// so that corners line up.
circle_detail = llceil(circle_detail / 4.0f) * 4.0f;
}
}
S32 sides = (S32)circle_detail;
if (is_sculpted)
sides = sculpt_size;
np = getNumNGonPoints(params, sides);
if (hollow)
{
np *= 2;
}
}
break;
case LL_PCODE_PROFILE_CIRCLE_HALF:
{
// If this has a square hollow, we should adjust the
// number of faces a bit so that the geometry lines up.
U8 hole_type=0;
// Number of faces is cut in half because it's only a half-circle.
F32 circle_detail = MIN_DETAIL_FACES * detail * 0.5f;
if (hollow)
{
hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK;
if (hole_type == LL_PCODE_HOLE_SQUARE)
{
// Snap to the next multiple of four sides (div 2),
// so that corners line up.
circle_detail = llceil(circle_detail / 2.0f) * 2.0f;
}
}
np = getNumNGonPoints(params, llfloor(circle_detail), 0.5f, 0.f, 0.5f);
if (hollow)
{
np *= 2;
}
// Special case for openness of sphere
if ((params.getEnd() - params.getBegin()) < 1.f)
{
}
else if (!hollow)
{
np++;
}
}
break;
default:
break;
};
return np;
}
BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split,
@ -1133,6 +1308,32 @@ LLPath::~LLPath()
{
}
S32 LLPath::getNumNGonPoints(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)
{ //this is basically LLPath::genNGon stripped down to only operations that influence the number of points added
S32 ret = 0;
F32 step= 1.0f / sides;
F32 t = params.getBegin();
ret = 1;
t+=step;
// Snap to a quantized parameter, so that cut does not
// affect most sample points.
t = ((S32)(t * sides)) / (F32)sides;
// Run through the non-cut dependent points.
while (t < params.getEnd())
{
ret++;
t+=step;
}
ret++;
return ret;
}
void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)
{
// Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane.
@ -1310,6 +1511,56 @@ const LLVector2 LLPathParams::getEndScale() const
return end_scale;
}
S32 LLPath::getNumPoints(const LLPathParams& params, F32 detail)
{ // this is basically LLPath::generate stripped down to only the operations that influence the number of points
LLMemType m1(LLMemType::MTYPE_VOLUME);
if (detail < MIN_LOD)
{
detail = MIN_LOD;
}
S32 np = 2; // hardcode for line
// Is this 0xf0 mask really necessary? DK 03/02/05
switch (params.getCurveType() & 0xf0)
{
default:
case LL_PCODE_PATH_LINE:
{
// Take the begin/end twist into account for detail.
np = llfloor(fabs(params.getTwistBegin() - params.getTwist()) * 3.5f * (detail-0.5f)) + 2;
}
break;
case LL_PCODE_PATH_CIRCLE:
{
// Increase the detail as the revolutions and twist increase.
F32 twist_mag = fabs(params.getTwistBegin() - params.getTwist());
S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * params.getRevolutions());
np = sides;
}
break;
case LL_PCODE_PATH_CIRCLE2:
{
//genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f);
np = getNumNGonPoints(params, llfloor(MIN_DETAIL_FACES * detail));
}
break;
case LL_PCODE_PATH_TEST:
np = 5;
break;
};
return np;
}
BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
BOOL is_sculpted, S32 sculpt_size)
{
@ -2159,27 +2410,41 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
U32 face_count = mdl.size();
if (face_count == 0)
{
llerrs << "WTF?" << llendl;
{ //no faces unpacked, treat as failed decode
llwarns << "found no faces!" << llendl;
return false;
}
mVolumeFaces.resize(face_count);
for (U32 i = 0; i < face_count; ++i)
{
LLVolumeFace& face = mVolumeFaces[i];
if (mdl[i].has("NoGeometry"))
{ //face has no geometry, continue
face.resizeIndices(3);
face.resizeVertices(1);
memset(face.mPositions, 0, sizeof(LLVector4a));
memset(face.mNormals, 0, sizeof(LLVector4a));
memset(face.mTexCoords, 0, sizeof(LLVector2));
memset(face.mIndices, 0, sizeof(U16)*3);
continue;
}
LLSD::Binary pos = mdl[i]["Position"];
LLSD::Binary norm = mdl[i]["Normal"];
LLSD::Binary tc = mdl[i]["TexCoord0"];
LLSD::Binary idx = mdl[i]["TriangleList"];
LLVolumeFace& face = mVolumeFaces[i];
//copy out indices
face.resizeIndices(idx.size()/2);
if (idx.empty() || face.mNumIndices < 3)
{ //why is there an empty index list?
llerrs <<"WTF?" << llendl;
llwarns <<"Empty face present!" << llendl;
continue;
}
@ -2377,14 +2642,20 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
LLVector4a& min = face.mExtents[0];
LLVector4a& max = face.mExtents[1];
min.clear();
max.clear();
min = max = face.mPositions[0];
for (S32 i = 1; i < face.mNumVertices; ++i)
if (face.mNumVertices < 3)
{ //empty face, use a dummy 1cm (at 1m scale) bounding box
min.splat(-0.005f);
max.splat(0.005f);
}
else
{
min.setMin(min, face.mPositions[i]);
max.setMax(max, face.mPositions[i]);
min = max = face.mPositions[0];
for (S32 i = 1; i < face.mNumVertices; ++i)
{
min.setMin(min, face.mPositions[i]);
max.setMax(max, face.mPositions[i]);
}
}
}
}
@ -2980,7 +3251,11 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components,
// don't test lowest LOD to support legacy content DEV-33670
if (mDetail > SCULPT_MIN_AREA_DETAIL)
{
if (sculptGetSurfaceArea() < SCULPT_MIN_AREA)
F32 area = sculptGetSurfaceArea();
const F32 SCULPT_MAX_AREA = 32.f;
if (area < SCULPT_MIN_AREA || area > SCULPT_MAX_AREA)
{
data_is_empty = TRUE;
}
@ -4064,6 +4339,23 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
return index;
}
void LLVolume::getLoDTriangleCounts(const LLVolumeParams& params, S32* counts)
{ //attempt to approximate the number of triangles that will result from generating a volume LoD set for the
//supplied LLVolumeParams -- inaccurate, but a close enough approximation for determining streaming cost
F32 detail[] = {1.f, 1.5f, 2.5f, 4.f};
for (S32 i = 0; i < 4; i++)
{
S32 count = 0;
S32 path_points = LLPath::getNumPoints(params.getPathParams(), detail[i]);
S32 profile_points = LLProfile::getNumPoints(params.getProfileParams(), false, detail[i]);
count = (profile_points-1)*2*(path_points-1);
count += profile_points*2;
counts[i] = count;
}
}
S32 LLVolume::getNumTriangleIndices() const
{
BOOL profile_open = getProfile().isOpen();
@ -5220,6 +5512,8 @@ LLVolumeFace::LLVolumeFace() :
mOctree(NULL)
{
mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);
mExtents[0].splat(-0.5f);
mExtents[1].splat(0.5f);
mCenter = mExtents+2;
}
@ -5741,6 +6035,11 @@ void LLVolumeFace::cacheOptimize()
LLVCacheLRU cache;
if (mNumVertices < 3)
{ //nothing to do
return;
}
//mapping of vertices to triangles and indices
std::vector<LLVCacheVertexData> vertex_data;

View File

@ -690,6 +690,9 @@ public:
BOOL isFlat(S32 face) const { return (mFaces[face].mCount == 2); }
BOOL isOpen() const { return mOpen; }
void setDirty() { mDirty = TRUE; }
static S32 getNumPoints(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0,
BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
BOOL generate(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0,
BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
BOOL isConcave() const { return mConcave; }
@ -714,6 +717,7 @@ public:
protected:
void genNormals(const LLProfileParams& params);
static S32 getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
void genNGon(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
Face* addHole(const LLProfileParams& params, BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split = 0);
@ -756,6 +760,9 @@ public:
virtual ~LLPath();
static S32 getNumPoints(const LLPathParams& params, F32 detail);
static S32 getNumNGonPoints(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f);
void genNGon(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f);
virtual BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0,
BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
@ -981,6 +988,7 @@ public:
// returns number of triangle indeces required for path/profile mesh
S32 getNumTriangleIndices() const;
static void getLoDTriangleCounts(const LLVolumeParams& params, S32* counts);
S32 getNumTriangles() const;

View File

@ -742,6 +742,7 @@ char const* const _PREHASH_MoneyData = LLMessageStringTable::getInstance()->getS
char const* const _PREHASH_ObjectDeselect = LLMessageStringTable::getInstance()->getString("ObjectDeselect");
char const* const _PREHASH_NewAssetID = LLMessageStringTable::getInstance()->getString("NewAssetID");
char const* const _PREHASH_ObjectAdd = LLMessageStringTable::getInstance()->getString("ObjectAdd");
char const* const _PREHASH_SimulatorFeatures = LLMessageStringTable::getInstance()->getString("SimulatorFeatures");
char const* const _PREHASH_RayEndIsIntersection = LLMessageStringTable::getInstance()->getString("RayEndIsIntersection");
char const* const _PREHASH_CompleteAuction = LLMessageStringTable::getInstance()->getString("CompleteAuction");
char const* const _PREHASH_CircuitCode = LLMessageStringTable::getInstance()->getString("CircuitCode");

View File

@ -742,6 +742,7 @@ extern char const* const _PREHASH_MoneyData;
extern char const* const _PREHASH_ObjectDeselect;
extern char const* const _PREHASH_NewAssetID;
extern char const* const _PREHASH_ObjectAdd;
extern char const* const _PREHASH_SimulatorFeatures;
extern char const* const _PREHASH_RayEndIsIntersection;
extern char const* const _PREHASH_CompleteAuction;
extern char const* const _PREHASH_CircuitCode;

View File

@ -34,6 +34,7 @@
#include "llsd.h"
#include "llhost.h"
#include "stringize.h"
#include <map>
#include <string>
#include <stdexcept>
#include <boost/lexical_cast.hpp>
@ -43,6 +44,58 @@ struct CommtestError: public std::runtime_error
CommtestError(const std::string& what): std::runtime_error(what) {}
};
static bool query_verbose()
{
const char* cbose = getenv("INTEGRATION_TEST_VERBOSE");
if (! cbose)
{
cbose = "1";
}
std::string strbose(cbose);
return (! (strbose == "0" || strbose == "off" ||
strbose == "false" || strbose == "quiet"));
}
bool verbose()
{
// This should only be initialized once.
static bool vflag = query_verbose();
return vflag;
}
static int query_port(const std::string& var)
{
const char* cport = getenv(var.c_str());
if (! cport)
{
throw CommtestError(STRINGIZE("missing environment variable" << var));
}
// This will throw, too, if the value of PORT isn't numeric.
int port(boost::lexical_cast<int>(cport));
if (verbose())
{
std::cout << "getport('" << var << "') = " << port << std::endl;
}
return port;
}
static int getport(const std::string& var)
{
typedef std::map<std::string, int> portsmap;
static portsmap ports;
// We can do this with a single map lookup with map::insert(). Either it
// returns an existing entry and 'false' (not newly inserted), or it
// inserts the specified value and 'true'.
std::pair<portsmap::iterator, bool> inserted(ports.insert(portsmap::value_type(var, 0)));
if (inserted.second)
{
// We haven't yet seen this var. Remember its value.
inserted.first->second = query_port(var);
}
// Return the (existing or new) iterator's value.
return inserted.first->second;
}
/**
* This struct is shared by a couple of standalone comm tests (ADD_COMM_BUILD_TEST).
*/
@ -71,13 +124,10 @@ struct commtest_data
static int getport(const std::string& var)
{
const char* port = getenv(var.c_str());
if (! port)
{
throw CommtestError("missing $PORT environment variable");
}
// This will throw, too, if the value of PORT isn't numeric.
return boost::lexical_cast<int>(port);
// We have a couple consumers of commtest_data::getport(). But we've
// since moved it out to the global namespace. So this is just a
// facade.
return ::getport(var);
}
bool outcome(const LLSD& _result, bool _success)

View File

@ -38,7 +38,7 @@ mydir = os.path.dirname(__file__) # expected to be .../indra/llmessage/tes
sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python"))
from indra.util.fastest_elementtree import parse as xml_parse
from indra.base import llsd
from testrunner import freeport, run, debug
from testrunner import freeport, run, debug, VERBOSE
class TestHTTPRequestHandler(BaseHTTPRequestHandler):
"""This subclass of BaseHTTPRequestHandler is to receive and echo
@ -72,10 +72,10 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):
## # assuming that the underlying XML parser reads its input file
## # incrementally. Unfortunately I haven't been able to make it work.
## tree = xml_parse(self.rfile)
## debug("Finished raw parse\n")
## debug("parsed XML tree %s\n" % tree)
## debug("parsed root node %s\n" % tree.getroot())
## debug("root node tag %s\n" % tree.getroot().tag)
## debug("Finished raw parse")
## debug("parsed XML tree %s", tree)
## debug("parsed root node %s", tree.getroot())
## debug("root node tag %s", tree.getroot().tag)
## return llsd.to_python(tree.getroot())
def do_GET(self):
@ -88,8 +88,10 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):
self.answer(self.read_xml())
def answer(self, data):
debug("%s.answer(%s): self.path = %r", self.__class__.__name__, data, self.path)
if "fail" not in self.path:
response = llsd.format_xml(data.get("reply", llsd.LLSD("success")))
debug("success: %s", response)
self.send_response(200)
self.send_header("Content-type", "application/llsd+xml")
self.send_header("Content-Length", str(len(response)))
@ -106,16 +108,21 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):
("fail requested",
"Your request specified failure status %s "
"without providing a reason" % status))[1])
debug("fail requested: %s: %r", status, reason)
self.send_error(status, reason)
def log_request(self, code, size=None):
# For present purposes, we don't want the request splattered onto
# stderr, as it would upset devs watching the test run
pass
if not VERBOSE:
# When VERBOSE is set, skip both these overrides because they exist to
# suppress output.
def log_error(self, format, *args):
# Suppress error output as well
pass
def log_request(self, code, size=None):
# For present purposes, we don't want the request splattered onto
# stderr, as it would upset devs watching the test run
pass
def log_error(self, format, *args):
# Suppress error output as well
pass
if __name__ == "__main__":
# Instantiate an HTTPServer(TestHTTPRequestHandler) on the first free port
@ -130,4 +137,5 @@ if __name__ == "__main__":
# command-line parsing -- and anyway, for C++ integration tests, that's
# performed in TUT code rather than our own.
os.environ["PORT"] = str(port)
debug("$PORT = %s", port)
sys.exit(run(server=Thread(name="httpd", target=httpd.serve_forever), *sys.argv[1:]))

View File

@ -29,14 +29,21 @@ $/LicenseInfo$
import os
import sys
import re
import errno
import socket
def debug(*args):
sys.stdout.writelines(args)
sys.stdout.flush()
# comment out the line below to enable debug output
debug = lambda *args: None
VERBOSE = os.environ.get("INTEGRATION_TEST_VERBOSE", "1") # default to verbose
# Support usage such as INTEGRATION_TEST_VERBOSE=off -- distressing to user if
# that construct actually turns on verbosity...
VERBOSE = not re.match(r"(0|off|false|quiet)$", VERBOSE, re.IGNORECASE)
if VERBOSE:
def debug(fmt, *args):
print fmt % args
sys.stdout.flush()
else:
debug = lambda *args: None
def freeport(portlist, expr):
"""
@ -78,44 +85,53 @@ def freeport(portlist, expr):
# pass 'port' to client code
# call server.serve_forever()
"""
# If portlist is completely empty, let StopIteration propagate: that's an
# error because we can't return meaningful values. We have no 'port',
# therefore no 'expr(port)'.
portiter = iter(portlist)
port = portiter.next()
try:
# If portlist is completely empty, let StopIteration propagate: that's an
# error because we can't return meaningful values. We have no 'port',
# therefore no 'expr(port)'.
portiter = iter(portlist)
port = portiter.next()
while True:
try:
# If this value of port works, return as promised.
return expr(port), port
except socket.error, err:
# Anything other than 'Address already in use', propagate
if err.args[0] != errno.EADDRINUSE:
raise
# Here we want the next port from portiter. But on StopIteration,
# we want to raise the original exception rather than
# StopIteration. So save the original exc_info().
type, value, tb = sys.exc_info()
while True:
try:
try:
port = portiter.next()
except StopIteration:
raise type, value, tb
finally:
# Clean up local traceback, see docs for sys.exc_info()
del tb
# If this value of port works, return as promised.
value = expr(port)
# Recap of the control flow above:
# If expr(port) doesn't raise, return as promised.
# If expr(port) raises anything but EADDRINUSE, propagate that
# exception.
# If portiter.next() raises StopIteration -- that is, if the port
# value we just passed to expr(port) was the last available -- reraise
# the EADDRINUSE exception.
# If we've actually arrived at this point, portiter.next() delivered a
# new port value. Loop back to pass that to expr(port).
except socket.error, err:
# Anything other than 'Address already in use', propagate
if err.args[0] != errno.EADDRINUSE:
raise
# Here we want the next port from portiter. But on StopIteration,
# we want to raise the original exception rather than
# StopIteration. So save the original exc_info().
type, value, tb = sys.exc_info()
try:
try:
port = portiter.next()
except StopIteration:
raise type, value, tb
finally:
# Clean up local traceback, see docs for sys.exc_info()
del tb
else:
debug("freeport() returning %s on port %s", value, port)
return value, port
# Recap of the control flow above:
# If expr(port) doesn't raise, return as promised.
# If expr(port) raises anything but EADDRINUSE, propagate that
# exception.
# If portiter.next() raises StopIteration -- that is, if the port
# value we just passed to expr(port) was the last available -- reraise
# the EADDRINUSE exception.
# If we've actually arrived at this point, portiter.next() delivered a
# new port value. Loop back to pass that to expr(port).
except Exception, err:
debug("*** freeport() raising %s: %s", err.__class__.__name__, err)
raise
def run(*args, **kwds):
"""All positional arguments collectively form a command line, executed as
@ -144,8 +160,7 @@ def run(*args, **kwds):
# - [no p] don't use the PATH because we specifically want to invoke the
# executable passed as our first arg,
# - [no e] child should inherit this process's environment.
debug("Running %s...\n" % (" ".join(args)))
sys.stdout.flush()
debug("Running %s...", " ".join(args))
rc = os.spawnv(os.P_WAIT, args[0], args)
debug("%s returned %s\n" % (args[0], rc))
debug("%s returned %s", args[0], rc)
return rc

View File

@ -50,7 +50,7 @@ std::string model_names[] =
"low_lod",
"medium_lod",
"high_lod",
"physics_shape"
"physics_mesh"
};
const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string);
@ -84,7 +84,7 @@ void load_face_from_dom_inputs(LLVolumeFace& face, const domInputLocalOffset_Arr
domInputLocal_Array& v_inp = vertices->getInput_array();
if (inputs[j]->getOffset() != 0)
{
llerrs << "WTF?" << llendl;
llerrs << "Vertex array offset MUST be zero." << llendl;
}
for (U32 k = 0; k < v_inp.getCount(); ++k)
@ -98,7 +98,7 @@ void load_face_from_dom_inputs(LLVolumeFace& face, const domInputLocalOffset_Arr
if (src->getTechnique_common()->getAccessor()->getStride() != 3)
{
llerrs << "WTF?" << llendl;
llerrs << "Vertex array stride MUST be three." << llendl;
}
domListOfFloats& v = src->getFloat_array()->getValue();
@ -149,9 +149,10 @@ void load_face_from_dom_inputs(LLVolumeFace& face, const domInputLocalOffset_Arr
}
}
void get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S32& tc_offset, S32& norm_offset, S32 &idx_stride,
bool get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S32& tc_offset, S32& norm_offset, S32 &idx_stride,
domSource* &pos_source, domSource* &tc_source, domSource* &norm_source)
{
idx_stride = 0;
for (U32 j = 0; j < inputs.getCount(); ++j)
@ -163,7 +164,11 @@ void get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S
const domURIFragmentType& uri = inputs[j]->getSource();
daeElementRef elem = uri.getElement();
domVertices* vertices = (domVertices*) elem.cast();
if ( !vertices )
{
return false;
}
domInputLocal_Array& v_inp = vertices->getInput_array();
@ -207,6 +212,8 @@ void get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S
}
idx_stride += 1;
return true;
}
LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& face_list, std::vector<std::string>& materials, domTrianglesRef& tri)
@ -227,8 +234,12 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
S32 idx_stride = 0;
get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source);
if ( !get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source) || !pos_source )
{
return LLModel::BAD_ELEMENT;
}
domPRef p = tri->getP();
domListOfUInts& idx = p->getValue();
@ -367,7 +378,10 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
S32 idx_stride = 0;
get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source);
if (!get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source))
{
return LLModel::BAD_ELEMENT;
}
LLVolumeFace face;
@ -564,7 +578,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
const domURIFragmentType& uri = inputs[i]->getSource();
daeElementRef elem = uri.getElement();
domVertices* vertices = (domVertices*) elem.cast();
if (!vertices)
{
return LLModel::BAD_ELEMENT;
}
domInputLocal_Array& v_inp = vertices->getInput_array();
for (U32 k = 0; k < v_inp.getCount(); ++k)
@ -574,6 +591,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
const domURIFragmentType& uri = v_inp[k]->getSource();
daeElementRef elem = uri.getElement();
domSource* src = (domSource*) elem.cast();
if (!src)
{
return LLModel::BAD_ELEMENT;
}
v = &(src->getFloat_array()->getValue());
}
}
@ -585,6 +606,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
const domURIFragmentType& uri = inputs[i]->getSource();
daeElementRef elem = uri.getElement();
domSource* src = (domSource*) elem.cast();
if (!src)
{
return LLModel::BAD_ELEMENT;
}
n = &(src->getFloat_array()->getValue());
}
else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[i]->getSemantic()) == 0 && inputs[i]->getSet() == 0)
@ -593,6 +618,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
const domURIFragmentType& uri = inputs[i]->getSource();
daeElementRef elem = uri.getElement();
domSource* src = (domSource*) elem.cast();
if (!src)
{
return LLModel::BAD_ELEMENT;
}
t = &(src->getFloat_array()->getValue());
}
}
@ -667,11 +696,6 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
}
}
if (cur_idx != vert_idx.size())
{
llerrs << "WTF?" << llendl;
}
//build vertex array from map
std::vector<LLVolumeFace::VertexData> new_verts;
new_verts.resize(vert_idx.size());
@ -717,7 +741,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
//static
std::string LLModel::getStatusString(U32 status)
{
const static std::string status_strings[(S32)INVALID_STATUS] = {"status_no_error", "status_vertex_number_overflow"};
const static std::string status_strings[(S32)INVALID_STATUS] = {"status_no_error", "status_vertex_number_overflow","bad_element"};
if(status < INVALID_STATUS)
{
@ -755,7 +779,6 @@ void LLModel::addVolumeFacesFromDomMesh(domMesh* mesh)
for (U32 i = 0; i < polys.getCount(); ++i)
{
domPolylistRef& poly = polys.get(i);
mStatus = load_face_from_dom_polylist(mVolumeFaces, mMaterialList, poly);
if(mStatus != NO_ERRORS)
@ -765,12 +788,12 @@ void LLModel::addVolumeFacesFromDomMesh(domMesh* mesh)
return ; //abort
}
}
domPolygons_Array& polygons = mesh->getPolygons_array();
for (U32 i = 0; i < polygons.getCount(); ++i)
{
domPolygonsRef& poly = polygons.get(i);
mStatus = load_face_from_dom_polygons(mVolumeFaces, mMaterialList, poly);
if(mStatus != NO_ERRORS)
@ -780,7 +803,7 @@ void LLModel::addVolumeFacesFromDomMesh(domMesh* mesh)
return ; //abort
}
}
}
BOOL LLModel::createVolumeFacesFromDomMesh(domMesh* mesh)
@ -926,11 +949,6 @@ void LLModel::normalizeVolumeFaces()
{
LLVector4a min, max;
if (mVolumeFaces[0].mNumVertices <= 0)
{
llerrs << "WTF?" << llendl;
}
// For all of the volume faces
// in the model, loop over
// them and see what the extents
@ -942,11 +960,6 @@ void LLModel::normalizeVolumeFaces()
{
LLVolumeFace& face = mVolumeFaces[i];
if (face.mNumVertices <= 0)
{
llerrs << "WTF?" << llendl;
}
update_min_max(min, max, face.mExtents[0]);
update_min_max(min, max, face.mExtents[1]);
}
@ -1289,11 +1302,6 @@ void LLModel::generateNormals(F32 angle_cutoff)
{
LLVector4a& n = iter->second[k].getNormal();
if (!iter->second[k].getPosition().equals3(new_face.mPositions[i]))
{
llerrs << "WTF?" << llendl;
}
F32 cur = n.dot3(ref_norm).getF32();
if (cur > best)
@ -1410,7 +1418,11 @@ LLSD LLModel::writeModel(
if (!decomp.mBaseHull.empty() ||
!decomp.mHull.empty())
{
mdl["decomposition"] = decomp.asLLSD();
mdl["physics_convex"] = decomp.asLLSD();
if (!decomp.mHull.empty())
{ //convex decomposition exists, physics mesh will not be used
model[LLModel::LOD_PHYSICS] = NULL;
}
}
for (U32 idx = 0; idx < MODEL_NAMES_LENGTH; ++idx)
@ -1435,8 +1447,9 @@ LLSD LLModel::writeModel(
for (S32 i = 0; i < model[idx]->getNumVolumeFaces(); ++i)
{ //for each face
const LLVolumeFace& face = model[idx]->getVolumeFace(i);
if (!face.mNumVertices)
if (face.mNumVertices < 3)
{ //don't export an empty face
mdl[model_names[idx]][i]["NoGeometry"] = true;
continue;
}
LLSD::Binary verts(face.mNumVertices*3*2);
@ -1469,7 +1482,6 @@ LLSD LLModel::writeModel(
//position + normal
for (U32 k = 0; k < 3; ++k)
{ //for each component
//convert to 16-bit normalized across domain
U16 val = (U16) (((pos[k]-min_pos.mV[k])/pos_range.mV[k])*65535);
@ -1513,7 +1525,6 @@ LLSD LLModel::writeModel(
//write out face data
mdl[model_names[idx]][i]["PositionDomain"]["Min"] = min_pos.getValue();
mdl[model_names[idx]][i]["PositionDomain"]["Max"] = max_pos.getValue();
mdl[model_names[idx]][i]["TexCoord0Domain"]["Min"] = min_tc.getValue();
mdl[model_names[idx]][i]["TexCoord0Domain"]["Max"] = max_tc.getValue();
@ -1539,11 +1550,6 @@ LLSD LLModel::writeModel(
weight_list& weights = high->getJointInfluences(pos);
if (weights.size() > 4)
{
llerrs << "WTF?" << llendl;
}
S32 count = 0;
for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter)
{
@ -1607,23 +1613,19 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite)
cur_offset += size;
bytes += size;
}
else
{
llerrs << "WTF?" << llendl;
}
}
std::string decomposition;
if (mdl.has("decomposition"))
if (mdl.has("physics_convex"))
{ //write out convex decomposition
decomposition = zip_llsd(mdl["decomposition"]);
decomposition = zip_llsd(mdl["physics_convex"]);
U32 size = decomposition.size();
if (size > 0)
{
header["decomposition"]["offset"] = (LLSD::Integer) cur_offset;
header["decomposition"]["size"] = (LLSD::Integer) size;
header["physics_convex"]["offset"] = (LLSD::Integer) cur_offset;
header["physics_convex"]["size"] = (LLSD::Integer) size;
cur_offset += size;
bytes += size;
}
@ -1644,11 +1646,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite)
cur_offset += size;
bytes += size;
}
else
{
header[model_names[i]]["offset"] = -1;
header[model_names[i]]["size"] = 0;
}
}
if (!nowrite)
@ -1662,7 +1659,7 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite)
if (!decomposition.empty())
{ //write decomposition block
ostr.write((const char*) decomposition.data(), header["decomposition"]["size"].asInteger());
ostr.write((const char*) decomposition.data(), header["physics_convex"]["size"].asInteger());
}
for (S32 i = 0; i < MODEL_NAMES_LENGTH; i++)
@ -1685,7 +1682,7 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)
{
if ((iter->first - pos).magVec() > 0.1f)
{
llerrs << "WTF?" << llendl;
llerrs << "Couldn't find weight list." << llendl;
}
return iter->second;
@ -1778,7 +1775,7 @@ void LLModel::updateHullCenters()
if (mHullPoints > 0)
{
mCenterOfHullCenters *= 1.f / mHullPoints;
llassert(mPhysics.asLLSD().has("HullList"));
llassert(mPhysics.hasHullList());
}
}
@ -1801,7 +1798,7 @@ bool LLModel::loadModel(std::istream& is)
"low_lod",
"medium_lod",
"high_lod",
"physics_shape",
"physics_mesh",
};
const S32 MODEL_LODS = 5;
@ -1900,8 +1897,8 @@ bool LLModel::loadSkinInfo(LLSD& header, std::istream &is)
bool LLModel::loadDecomposition(LLSD& header, std::istream& is)
{
S32 offset = header["decomposition"]["offset"].asInteger();
S32 size = header["decomposition"]["size"].asInteger();
S32 offset = header["physics_convex"]["offset"].asInteger();
S32 size = header["physics_convex"]["size"].asInteger();
if (offset >= 0 && size > 0)
{
@ -2041,7 +2038,7 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
{
// updated for const-correctness. gcc is picky about this type of thing - Nyx
const LLSD::Binary& hulls = decomp["HullList"].asBinary();
const LLSD::Binary& position = decomp["Position"].asBinary();
const LLSD::Binary& position = decomp["Positions"].asBinary();
U16* p = (U16*) &position[0];
@ -2051,11 +2048,19 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
LLVector3 max;
LLVector3 range;
min.setValue(decomp["Min"]);
max.setValue(decomp["Max"]);
if (decomp.has("Min"))
{
min.setValue(decomp["Min"]);
max.setValue(decomp["Max"]);
}
else
{
min.set(-0.5f, -0.5f, -0.5f);
max.set(0.5f, 0.5f, 0.5f);
}
range = max-min;
for (U32 i = 0; i < hulls.size(); ++i)
{
U16 count = (hulls[i] == 0) ? 256 : hulls[i];
@ -2071,6 +2076,7 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
//point must be unique
//llassert(valid.find(test) == valid.end());
valid.insert(test);
mHull[i].push_back(LLVector3(
(F32) p[0]/65535.f*range.mV[0]+min.mV[0],
(F32) p[1]/65535.f*range.mV[1]+min.mV[1],
@ -2085,9 +2091,9 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
}
}
if (decomp.has("Hull"))
if (decomp.has("BoundingVerts"))
{
const LLSD::Binary& position = decomp["Hull"].asBinary();
const LLSD::Binary& position = decomp["BoundingVerts"].asBinary();
U16* p = (U16*) &position[0];
@ -2123,10 +2129,15 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
{
//empty base hull mesh to indicate decomposition has been loaded
//but contains no base hull
mBaseHullMesh.clear();;
mBaseHullMesh.clear();
}
}
bool LLModel::Decomposition::hasHullList() const
{
return !mHull.empty() ;
}
LLSD LLModel::Decomposition::asLLSD() const
{
LLSD ret;
@ -2137,11 +2148,9 @@ LLSD LLModel::Decomposition::asLLSD() const
}
//write decomposition block
// ["decomposition"]["HullList"] -- list of 8 bit integers, each entry represents a hull with specified number of points
// ["decomposition"]["PositionDomain"]["Min"/"Max"]
// ["decomposition"]["Position"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points
// ["decomposition"]["Hull"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points representing a single hull approximation of given shape
// ["physics_convex"]["HullList"] -- list of 8 bit integers, each entry represents a hull with specified number of points
// ["physics_convex"]["Position"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points
// ["physics_convex"]["BoundingVerts"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points representing a single hull approximation of given shape
//get minimum and maximum
LLVector3 min;
@ -2190,6 +2199,8 @@ LLSD LLModel::Decomposition::asLLSD() const
{
LLSD::Binary p(total*3*2);
LLVector3 min(-0.5f, -0.5f, -0.5f);
LLVector3 max(0.5f, 0.5f, 0.5f);
LLVector3 range = max-min;
U32 vert_idx = 0;
@ -2205,17 +2216,24 @@ LLSD LLModel::Decomposition::asLLSD() const
U64 test = 0;
for (U32 k = 0; k < 3; k++)
{
F32* src = (F32*) (mHull[i][j].mV);
llassert(src[k] <= 0.501f && src[k] >= -0.501f);
//convert to 16-bit normalized across domain
U16 val = (U16) (((mHull[i][j].mV[k]-min.mV[k])/range.mV[k])*65535);
U16 val = (U16) (((src[k]-min.mV[k])/range.mV[k])*65535);
switch (k)
if(valid.size() < 3)
{
case 0: test = test | (U64) val; break;
case 1: test = test | ((U64) val << 16); break;
case 2: test = test | ((U64) val << 32); break;
};
switch (k)
{
case 0: test = test | (U64) val; break;
case 1: test = test | ((U64) val << 16); break;
case 2: test = test | ((U64) val << 32); break;
};
valid.insert(test);
valid.insert(test);
}
U8* buff = (U8*) &val;
//write to binary buffer
@ -2227,17 +2245,21 @@ LLSD LLModel::Decomposition::asLLSD() const
}
}
//must have at least 4 unique points
llassert(valid.size() > 3);
//must have at least 3 unique points
llassert(valid.size() > 2);
}
ret["Position"] = p;
ret["Positions"] = p;
}
//llassert(!mBaseHull.empty());
if (!mBaseHull.empty())
{
LLSD::Binary p(mBaseHull.size()*3*2);
LLVector3 min(-0.5f, -0.5f, -0.5f);
LLVector3 max(0.5f, 0.5f, 0.5f);
LLVector3 range = max-min;
U32 vert_idx = 0;
@ -2245,6 +2267,8 @@ LLSD LLModel::Decomposition::asLLSD() const
{
for (U32 k = 0; k < 3; k++)
{
llassert(mBaseHull[j].mV[k] <= 0.51f && mBaseHull[j].mV[k] >= -0.51f);
//convert to 16-bit normalized across domain
U16 val = (U16) (((mBaseHull[j].mV[k]-min.mV[k])/range.mV[k])*65535);
@ -2255,12 +2279,12 @@ LLSD LLModel::Decomposition::asLLSD() const
if (vert_idx > p.size())
{
llerrs << "WTF?" << llendl;
llerrs << "Index out of bounds" << llendl;
}
}
}
ret["Hull"] = p;
ret["BoundingVerts"] = p;
}
return ret;
@ -2290,10 +2314,5 @@ void LLModel::Decomposition::merge(const LLModel::Decomposition* rhs)
{ //take physics shape mesh from rhs
mPhysicsShapeMesh = rhs->mPhysicsShapeMesh;
}
if (!mHull.empty())
{ //verify
llassert(asLLSD().has("HullList"));
}
}

View File

@ -73,6 +73,7 @@ public:
{
NO_ERRORS = 0,
VERTEX_NUMBER_OVERFLOW, //vertex number is >= 65535.
BAD_ELEMENT,
INVALID_STATUS
} ;
@ -106,6 +107,7 @@ public:
Decomposition(LLSD& data);
void fromLLSD(LLSD& data);
LLSD asLLSD() const;
bool hasHullList() const;
void merge(const Decomposition* rhs);

View File

@ -127,6 +127,11 @@ PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = NULL;
PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB = NULL;
PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB = NULL;
// GL_ARB_map_buffer_range
PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange;
// vertex object prototypes
PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI = NULL;
PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI = NULL;
@ -178,6 +183,12 @@ PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer = NULL;
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample = NULL;
PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer = NULL;
//GL_ARB_texture_multisample
PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
PFNGLSAMPLEMASKIPROC glSampleMaski;
// GL_EXT_blend_func_separate
PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT = NULL;
@ -321,9 +332,11 @@ LLGLManager::LLGLManager() :
mHasMipMapGeneration(FALSE),
mHasCompressedTextures(FALSE),
mHasFramebufferObject(FALSE),
mMaxSamples(0),
mHasBlendFuncSeparate(FALSE),
mHasVertexBufferObject(FALSE),
mHasMapBufferRange(FALSE),
mHasPBuffer(FALSE),
mHasShaderObjects(FALSE),
mHasVertexShader(FALSE),
@ -334,6 +347,11 @@ LLGLManager::LLGLManager() :
mHasPointParameters(FALSE),
mHasDrawBuffers(FALSE),
mHasTextureRectangle(FALSE),
mHasTextureMultisample(FALSE),
mMaxSampleMaskWords(0),
mMaxColorTextureSamples(0),
mMaxDepthTextureSamples(0),
mMaxIntegerSamples(0),
mHasAnisotropic(FALSE),
mHasARBEnvCombine(FALSE),
@ -539,7 +557,20 @@ bool LLGLManager::initGL()
{
GLint num_tex_image_units;
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
mNumTextureImageUnits = num_tex_image_units;
mNumTextureImageUnits = llmin(num_tex_image_units, 32);
}
if (mHasTextureMultisample)
{
glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &mMaxColorTextureSamples);
glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &mMaxDepthTextureSamples);
glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples);
glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords);
}
if (mHasFramebufferObject)
{
glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples);
}
setToDebugGPU();
@ -648,6 +679,14 @@ std::string LLGLManager::getRawGLString()
return gl_string;
}
U32 LLGLManager::getNumFBOFSAASamples(U32 samples)
{
samples = llmin(samples, (U32) mMaxColorTextureSamples);
samples = llmin(samples, (U32) mMaxDepthTextureSamples);
samples = llmin(samples, (U32) 4);
return samples;
}
void LLGLManager::shutdownGL()
{
if (mInited)
@ -728,6 +767,7 @@ void LLGLManager::initExtensions()
mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);
mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts);
mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
mHasMapBufferRange = ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts);
mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad
#ifdef GL_ARB_framebuffer_object
@ -742,6 +782,7 @@ void LLGLManager::initExtensions()
mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts);
mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts);
mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts);
mHasTextureMultisample = ExtensionExists("GL_ARB_texture_multisample", gGLHExts.mSysExts);
#if !LL_DARWIN
mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
#endif
@ -921,6 +962,11 @@ void LLGLManager::initExtensions()
mHasVertexBufferObject = FALSE;
}
}
if (mHasMapBufferRange)
{
glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glMapBufferRange");
glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glFlushMappedBufferRange");
}
if (mHasFramebufferObject)
{
llinfos << "initExtensions() FramebufferObject-related procs..." << llendl;
@ -953,6 +999,13 @@ void LLGLManager::initExtensions()
{
glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBlendFuncSeparateEXT");
}
if (mHasTextureMultisample)
{
glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage2DMultisample");
glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage3DMultisample");
glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetMultisamplefv");
glSampleMaski = (PFNGLSAMPLEMASKIPROC) GLH_EXT_GET_PROC_ADDRESS("glSampleMaski");
}
#if (!LL_LINUX && !LL_SOLARIS) || LL_LINUX_NV_GL_HEADERS
// This is expected to be a static symbol on Linux GL implementations, except if we use the nvidia headers - bah
glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
@ -1370,10 +1423,6 @@ void LLGLState::checkTextureChannels(const std::string& msg)
}
}
GLint maxTextureUnits = 0;
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits);
stop_glerror();
static const char* label[] =
{
"GL_TEXTURE_2D",
@ -1384,7 +1433,8 @@ void LLGLState::checkTextureChannels(const std::string& msg)
"GL_TEXTURE_GEN_T",
"GL_TEXTURE_GEN_Q",
"GL_TEXTURE_GEN_R",
"GL_TEXTURE_RECTANGLE_ARB"
"GL_TEXTURE_RECTANGLE_ARB",
"GL_TEXTURE_2D_MULTISAMPLE"
};
static GLint value[] =
@ -1397,7 +1447,8 @@ void LLGLState::checkTextureChannels(const std::string& msg)
GL_TEXTURE_GEN_T,
GL_TEXTURE_GEN_Q,
GL_TEXTURE_GEN_R,
GL_TEXTURE_RECTANGLE_ARB
GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_2D_MULTISAMPLE
};
GLint stackDepth = 0;
@ -1406,68 +1457,96 @@ void LLGLState::checkTextureChannels(const std::string& msg)
glh::matrix4f identity;
identity.identity();
for (GLint i = 1; i < maxTextureUnits; i++)
for (GLint i = 1; i < gGLManager.mNumTextureUnits; i++)
{
gGL.getTexUnit(i)->activate();
glClientActiveTextureARB(GL_TEXTURE0_ARB+i);
stop_glerror();
glGetIntegerv(GL_TEXTURE_STACK_DEPTH, &stackDepth);
stop_glerror();
if (stackDepth != 1)
if (i < gGLManager.mNumTextureUnits)
{
error = TRUE;
LL_WARNS("RenderState") << "Texture matrix stack corrupted." << LL_ENDL;
glClientActiveTextureARB(GL_TEXTURE0_ARB+i);
stop_glerror();
glGetIntegerv(GL_TEXTURE_STACK_DEPTH, &stackDepth);
stop_glerror();
if (gDebugSession)
{
gFailLog << "Texture matrix stack corrupted." << std::endl;
}
}
glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) mat.m);
stop_glerror();
if (mat != identity)
{
error = TRUE;
LL_WARNS("RenderState") << "Texture matrix in channel " << i << " corrupt." << LL_ENDL;
if (gDebugSession)
{
gFailLog << "Texture matrix in channel " << i << " corrupt." << std::endl;
}
}
for (S32 j = (i == 0 ? 1 : 0);
j < (gGLManager.mHasTextureRectangle ? 9 : 8); j++)
{
if (glIsEnabled(value[j]))
if (stackDepth != 1)
{
error = TRUE;
LL_WARNS("RenderState") << "Texture channel " << i << " still has " << label[j] << " enabled." << LL_ENDL;
LL_WARNS("RenderState") << "Texture matrix stack corrupted." << LL_ENDL;
if (gDebugSession)
{
gFailLog << "Texture channel " << i << " still has " << label[j] << " enabled." << std::endl;
gFailLog << "Texture matrix stack corrupted." << std::endl;
}
}
glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) mat.m);
stop_glerror();
if (mat != identity)
{
error = TRUE;
LL_WARNS("RenderState") << "Texture matrix in channel " << i << " corrupt." << LL_ENDL;
if (gDebugSession)
{
gFailLog << "Texture matrix in channel " << i << " corrupt." << std::endl;
}
}
for (S32 j = (i == 0 ? 1 : 0);
j < 9; j++)
{
if (j == 8 && !gGLManager.mHasTextureRectangle ||
j == 9 && !gGLManager.mHasTextureMultisample)
{
continue;
}
if (glIsEnabled(value[j]))
{
error = TRUE;
LL_WARNS("RenderState") << "Texture channel " << i << " still has " << label[j] << " enabled." << LL_ENDL;
if (gDebugSession)
{
gFailLog << "Texture channel " << i << " still has " << label[j] << " enabled." << std::endl;
}
}
stop_glerror();
}
glGetFloatv(GL_TEXTURE_MATRIX, mat.m);
stop_glerror();
if (mat != identity)
{
error = TRUE;
LL_WARNS("RenderState") << "Texture matrix " << i << " is not identity." << LL_ENDL;
if (gDebugSession)
{
gFailLog << "Texture matrix " << i << " is not identity." << std::endl;
}
}
}
glGetFloatv(GL_TEXTURE_MATRIX, mat.m);
stop_glerror();
if (mat != identity)
{
error = TRUE;
LL_WARNS("RenderState") << "Texture matrix " << i << " is not identity." << LL_ENDL;
if (gDebugSession)
GLint tex = 0;
stop_glerror();
glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex);
stop_glerror();
if (tex != 0)
{
gFailLog << "Texture matrix " << i << " is not identity." << std::endl;
error = TRUE;
LL_WARNS("RenderState") << "Texture channel " << i << " still has texture " << tex << " bound." << llendl;
if (gDebugSession)
{
gFailLog << "Texture channel " << i << " still has texture " << tex << " bound." << std::endl;
}
}
}
}
stop_glerror();
gGL.getTexUnit(0)->activate();
glClientActiveTextureARB(GL_TEXTURE0_ARB);
stop_glerror();

View File

@ -83,10 +83,12 @@ public:
BOOL mHasMipMapGeneration;
BOOL mHasCompressedTextures;
BOOL mHasFramebufferObject;
S32 mMaxSamples;
BOOL mHasBlendFuncSeparate;
// ARB Extensions
BOOL mHasVertexBufferObject;
BOOL mHasMapBufferRange;
BOOL mHasPBuffer;
BOOL mHasShaderObjects;
BOOL mHasVertexShader;
@ -98,6 +100,11 @@ public:
BOOL mHasDrawBuffers;
BOOL mHasDepthClamp;
BOOL mHasTextureRectangle;
BOOL mHasTextureMultisample;
S32 mMaxSampleMaskWords;
S32 mMaxColorTextureSamples;
S32 mMaxDepthTextureSamples;
S32 mMaxIntegerSamples;
// Other extensions.
BOOL mHasAnisotropic;
@ -139,6 +146,7 @@ public:
void printGLInfoString();
void getGLInfo(LLSD& info);
U32 getNumFBOFSAASamples(U32 desired_samples = 32);
// In ALL CAPS
std::string mGLVendor;
std::string mGLVendorShort;

View File

@ -68,6 +68,10 @@ extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB;
extern PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB;
extern PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB;
// GL_ARB_map_buffer_range
extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange;
// GL_ATI_vertex_array_object
extern PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI;
extern PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI;
@ -306,6 +310,10 @@ extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB;
extern PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB;
extern PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB;
// GL_ARB_map_buffer_range
extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange;
// GL_ATI_vertex_array_object
extern PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI;
extern PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI;
@ -474,6 +482,11 @@ extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer;
//GL_ARB_draw_buffers
extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;
//GL_ARB_texture_multisample
extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
extern PFNGLSAMPLEMASKIPROC glSampleMaski;
#elif LL_WINDOWS
//----------------------------------------------------------------------------
@ -506,6 +519,10 @@ extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB;
extern PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB;
extern PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB;
// GL_ARB_map_buffer_range
extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange;
// GL_ATI_vertex_array_object
extern PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI;
extern PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI;
@ -673,6 +690,11 @@ extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer;
//GL_ARB_draw_buffers
extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;
//GL_ARB_texture_multisample
extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
extern PFNGLSAMPLEMASKIPROC glSampleMaski;
#elif LL_DARWIN
//----------------------------------------------------------------------------
@ -714,13 +736,55 @@ extern void glGenerateMipmapEXT(GLenum target) AVAILABLE_MAC_OS_X_VERSION_10_4_A
#ifndef GL_ARB_framebuffer_object
#define glGenerateMipmap glGenerateMipmapEXT
#define GL_MAX_SAMPLES 0x8D57
#endif
// GL_ARB_draw_buffers
extern void glDrawBuffersARB(GLsizei n, const GLenum* bufs) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
#ifdef __cplusplus
extern "C" {
#endif
//
// Define map buffer range headers on Mac
//
#ifndef GL_ARB_map_buffer_range
#define GL_MAP_READ_BIT 0x0001
#define GL_MAP_WRITE_BIT 0x0002
#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
#endif
//
// Define multisample headers on Mac
//
#ifndef GL_ARB_texture_multisample
#define GL_SAMPLE_POSITION 0x8E50
#define GL_SAMPLE_MASK 0x8E51
#define GL_SAMPLE_MASK_VALUE 0x8E52
#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101
#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103
#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105
#define GL_TEXTURE_SAMPLES 0x9106
#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
#define GL_SAMPLER_2D_MULTISAMPLE 0x9108
#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E
#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F
#define GL_MAX_INTEGER_SAMPLES 0x9110
#endif
//
// Define vertex buffer object headers on Mac
//
@ -757,7 +821,7 @@ extern "C" {
#define GL_DYNAMIC_READ_ARB 0x88E9
#define GL_DYNAMIC_COPY_ARB 0x88EA
#endif
#ifndef GL_ARB_vertex_buffer_object

View File

@ -48,6 +48,8 @@ using std::pair;
using std::make_pair;
using std::string;
GLhandleARB LLGLSLShader::sCurBoundShader = 0;
BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
{
return v1 != v2;
@ -56,7 +58,7 @@ BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
LLShaderFeatures::LLShaderFeatures()
: calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false),
hasTransport(false), hasSkinning(false), hasObjectSkinning(false), hasAtmospherics(false), isSpecular(false),
hasGamma(false), hasLighting(false), calculatesAtmospherics(false)
hasGamma(false), hasLighting(false), calculatesAtmospherics(false), mIndexedTextureChannels(0), disableTextureIndex(false)
{
}
@ -107,16 +109,11 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
// Create program
mProgramObject = glCreateProgramObjectARB();
// Attach existing objects
if (!LLShaderMgr::instance()->attachShaderFeatures(this))
{
return FALSE;
}
//compile new source
vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
for ( ; fileIter != mShaderFiles.end(); fileIter++ )
{
GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second);
GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, mFeatures.mIndexedTextureChannels);
LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
if (shaderhandle > 0)
{
@ -128,6 +125,12 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
}
}
// Attach existing objects
if (!LLShaderMgr::instance()->attachShaderFeatures(this))
{
return FALSE;
}
// Map attributes and uniforms
if (success)
{
@ -149,6 +152,29 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
return createShader(attributes,uniforms);
}
}
else if (mFeatures.mIndexedTextureChannels > 0)
{ //override texture channels for indexed texture rendering
bind();
S32 channel_count = mFeatures.mIndexedTextureChannels;
for (S32 i = 0; i < channel_count; i++)
{
uniform1i(llformat("tex%d", i), i);
}
S32 cur_tex = channel_count; //adjust any texture channels that might have been overwritten
for (U32 i = 0; i < mTexture.size(); i++)
{
if (mTexture[i] > -1 && mTexture[i] < channel_count)
{
llassert(cur_tex < gGLManager.mNumTextureImageUnits);
uniform1i(i, cur_tex);
mTexture[i] = cur_tex++;
}
}
unbind();
}
return success;
}
@ -293,7 +319,8 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
{
if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB)
if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB ||
type == GL_SAMPLER_2D_MULTISAMPLE)
{ //this here is a texture
glUniform1iARB(location, mActiveTextureChannels);
LL_DEBUGS("ShaderLoading") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL;
@ -342,7 +369,7 @@ void LLGLSLShader::bind()
if (gGLManager.mHasShaderObjects)
{
glUseProgramObjectARB(mProgramObject);
sCurBoundShader = mProgramObject;
if (mUniformsDirty)
{
LLShaderMgr::instance()->updateShaderUniforms(this);
@ -365,6 +392,7 @@ void LLGLSLShader::unbind()
}
}
glUseProgramObjectARB(0);
sCurBoundShader = 0;
stop_glerror();
}
}
@ -372,6 +400,7 @@ void LLGLSLShader::unbind()
void LLGLSLShader::bindNoShader(void)
{
glUseProgramObjectARB(0);
sCurBoundShader = 0;
}
S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)

View File

@ -45,6 +45,8 @@ public:
bool hasObjectSkinning;
bool hasAtmospherics;
bool hasGamma;
S32 mIndexedTextureChannels;
bool disableTextureIndex;
// char numLights;
@ -64,6 +66,8 @@ public:
LLGLSLShader();
static GLhandleARB sCurBoundShader;
void unload();
BOOL createShader(std::vector<std::string> * attributes,
std::vector<std::string> * uniforms);

View File

@ -1083,12 +1083,17 @@ void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
}
// static
void LLImageGL::deleteTextures(S32 numTextures, U32 *textures)
void LLImageGL::deleteTextures(S32 numTextures, U32 *textures, bool immediate)
{
for (S32 i = 0; i < numTextures; i++)
{
sDeadTextureList.push_back(textures[i]);
}
if (immediate)
{
LLImageGL::deleteDeadTextures();
}
}
// static
@ -1413,11 +1418,13 @@ void LLImageGL::deleteDeadTextures()
{
GLuint tex = sDeadTextureList.front();
sDeadTextureList.pop_front();
for (int i = 0; i < gGLManager.mNumTextureUnits; i++)
for (int i = 0; i < gGLManager.mNumTextureImageUnits; i++)
{
if (sCurrentBoundTextures[i] == tex)
LLTexUnit* tex_unit = gGL.getTexUnit(i);
if (tex_unit->getCurrTexture() == tex)
{
gGL.getTexUnit(i)->unbind(LLTexUnit::TT_TEXTURE);
tex_unit->unbind(tex_unit->getCurrType());
stop_glerror();
}
}

View File

@ -98,7 +98,7 @@ public:
// These 3 functions currently wrap glGenTextures(), glDeleteTextures(), and glTexImage2D()
// for tracking purposes and will be deprecated in the future
static void generateTextures(S32 numTextures, U32 *textures);
static void deleteTextures(S32 numTextures, U32 *textures);
static void deleteTextures(S32 numTextures, U32 *textures, bool immediate = false);
static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels);
BOOL createGLTexture() ;

View File

@ -30,6 +30,7 @@
#include "llvertexbuffer.h"
#include "llcubemap.h"
#include "llglslshader.h"
#include "llimagegl.h"
#include "llrendertarget.h"
#include "lltexture.h"
@ -46,14 +47,15 @@ S32 gGLViewport[4];
U32 LLRender::sUICalls = 0;
U32 LLRender::sUIVerts = 0;
static const U32 LL_NUM_TEXTURE_LAYERS = 16;
static const U32 LL_NUM_TEXTURE_LAYERS = 32;
static const U32 LL_NUM_LIGHT_UNITS = 8;
static GLenum sGLTextureType[] =
{
GL_TEXTURE_2D,
GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_CUBE_MAP_ARB
GL_TEXTURE_CUBE_MAP_ARB,
GL_TEXTURE_2D_MULTISAMPLE
};
static GLint sGLAddressMode[] =
@ -124,7 +126,7 @@ void LLTexUnit::refreshState(void)
// Per apple spec, don't call glEnable/glDisable when index exceeds max texture units
// http://www.mailinglistarchive.com/html/mac-opengl@lists.apple.com/2008-07/msg00653.html
//
bool enableDisable = (mIndex < gGLManager.mNumTextureUnits);
bool enableDisable = (mIndex < gGLManager.mNumTextureUnits) && mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE;
if (mCurrTexType != TT_NONE)
{
@ -182,8 +184,8 @@ void LLTexUnit::enable(eTextureType type)
mCurrTexType = type;
gGL.flush();
if (mIndex < gGLManager.mNumTextureUnits)
if (type != LLTexUnit::TT_MULTISAMPLE_TEXTURE &&
mIndex < gGLManager.mNumTextureUnits)
{
glEnable(sGLTextureType[type]);
}
@ -199,8 +201,8 @@ void LLTexUnit::disable(void)
activate();
unbind(mCurrTexType);
gGL.flush();
if (mIndex < gGLManager.mNumTextureUnits)
if (mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE &&
mIndex < gGLManager.mNumTextureUnits)
{
glDisable(sGLTextureType[mCurrTexType]);
}
@ -292,7 +294,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind)
glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture);
texture->updateBindStats(texture->mTextureMemory);
mHasMipMaps = texture->mHasMipMaps;
if (texture->mTexOptionsDirty)
if (mIndex == 0 && texture->mTexOptionsDirty)
{
texture->mTexOptionsDirty = false;
setTextureAddressMode(texture->mAddressMode);
@ -402,6 +404,7 @@ void LLTexUnit::unbind(eTextureType type)
activate();
mCurrTexture = 0;
glBindTexture(sGLTextureType[type], 0);
stop_glerror();
}
}
@ -423,7 +426,7 @@ void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode)
void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option)
{
if (mIndex < 0 || mCurrTexture == 0) return;
if (mIndex < 0 || mCurrTexture == 0 || mCurrTexType == LLTexUnit::TT_MULTISAMPLE_TEXTURE) return;
gGL.flush();

View File

@ -57,6 +57,7 @@ public:
TT_TEXTURE = 0, // Standard 2D Texture
TT_RECT_TEXTURE, // Non power of 2 texture
TT_CUBE_MAP, // 6-sided cube map texture
TT_MULTISAMPLE_TEXTURE, // see GL_ARB_texture_multisample
TT_NONE // No texture type is currently enabled
} eTextureType;

View File

@ -63,8 +63,7 @@ LLRenderTarget::LLRenderTarget() :
mUseDepth(false),
mRenderDepth(false),
mUsage(LLTexUnit::TT_TEXTURE),
mSamples(0),
mSampleBuffer(NULL)
mSamples(0)
{
}
@ -73,23 +72,32 @@ LLRenderTarget::~LLRenderTarget()
release();
}
void LLRenderTarget::setSampleBuffer(LLMultisampleBuffer* buffer)
{
mSampleBuffer = buffer;
}
void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo)
void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples)
{
stop_glerror();
release();
mResX = resx;
mResY = resy;
mStencil = stencil;
mUsage = usage;
mUseDepth = depth;
mSamples = samples;
release();
mSamples = gGLManager.getNumFBOFSAASamples(mSamples);
if (mSamples > 1 && gGLManager.mHasTextureMultisample)
{
mUsage = LLTexUnit::TT_MULTISAMPLE_TEXTURE;
//no support for multisampled stencil targets yet
mStencil = false;
}
else
{
mSamples = 0;
}
if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
{
@ -146,29 +154,51 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt)
stop_glerror();
LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
#ifdef GL_ARB_texture_multisample
if (mSamples > 1)
{
glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, color_fmt, mResX, mResY, GL_TRUE);
}
else
#else
llassert_always(mSamples <= 1);
#endif
{
LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
stop_glerror();
if (offset == 0)
{
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
}
else
{ //don't filter data attachments
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
{
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR);
}
else
{
// ATI doesn't support mirrored repeat for rectangular textures.
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
if (mSamples == 0)
{
if (offset == 0)
{ //use bilinear filtering on single texture render targets that aren't multisampled
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
stop_glerror();
}
else
{ //don't filter data attachments
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
stop_glerror();
}
if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
{
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR);
stop_glerror();
}
else
{
// ATI doesn't support mirrored repeat for rectangular textures.
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
stop_glerror();
}
}
if (mFBO)
{
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset,
LLTexUnit::getInternalType(mUsage), tex, 0);
@ -181,6 +211,12 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt)
mTex.push_back(tex);
if (gDebugGL)
{ //bind and unbind to validate target
bindTarget();
flush();
}
}
void LLRenderTarget::allocateDepth()
@ -197,9 +233,20 @@ void LLRenderTarget::allocateDepth()
{
LLImageGL::generateTextures(1, &mDepth);
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
U32 internal_type = LLTexUnit::getInternalType(mUsage);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT32, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
if (mSamples == 0)
{
U32 internal_type = LLTexUnit::getInternalType(mUsage);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT32, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
}
#ifdef GL_ARB_texture_multisample
else
{
glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, GL_DEPTH_COMPONENT32, mResX, mResY, GL_TRUE);
}
#else
llassert_always(mSamples <= 1);
#endif
}
}
@ -239,6 +286,9 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
stop_glerror();
}
check_framebuffer_status();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
target.mUseDepth = true;
@ -256,7 +306,7 @@ void LLRenderTarget::release()
}
else
{
LLImageGL::deleteTextures(1, &mDepth);
LLImageGL::deleteTextures(1, &mDepth, true);
stop_glerror();
}
mDepth = 0;
@ -285,11 +335,12 @@ void LLRenderTarget::release()
if (mTex.size() > 0)
{
LLImageGL::deleteTextures(mTex.size(), &mTex[0]);
LLImageGL::deleteTextures(mTex.size(), &mTex[0], true);
mTex.clear();
}
mResX = mResY = 0;
mSampleBuffer = NULL;
sBoundTarget = NULL;
}
@ -298,34 +349,27 @@ void LLRenderTarget::bindTarget()
if (mFBO)
{
stop_glerror();
if (mSampleBuffer)
{
mSampleBuffer->bindTarget(this);
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
stop_glerror();
if (gGLManager.mHasDrawBuffers)
{ //setup multiple render targets
GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3};
glDrawBuffersARB(mTex.size(), drawbuffers);
}
else
{
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
stop_glerror();
if (gGLManager.mHasDrawBuffers)
{ //setup multiple render targets
GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3};
glDrawBuffersARB(mTex.size(), drawbuffers);
}
if (mTex.empty())
{ //no color buffer to draw to
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
}
check_framebuffer_status();
stop_glerror();
if (mTex.empty())
{ //no color buffer to draw to
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
}
check_framebuffer_status();
stop_glerror();
}
glViewport(0, 0, mResX, mResY);
@ -407,50 +451,8 @@ void LLRenderTarget::flush(bool fetch_depth)
else
{
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
stop_glerror();
if (mSampleBuffer)
{
LLGLEnable multisample(GL_MULTISAMPLE);
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
stop_glerror();
check_framebuffer_status();
glBindFramebuffer(GL_READ_FRAMEBUFFER, mSampleBuffer->mFBO);
check_framebuffer_status();
stop_glerror();
glBlitFramebuffer(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
stop_glerror();
if (mTex.size() > 1)
{
for (U32 i = 1; i < mTex.size(); ++i)
{
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
LLTexUnit::getInternalType(mUsage), mTex[i], 0);
stop_glerror();
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mSampleBuffer->mTex[i]);
stop_glerror();
glBlitFramebuffer(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT, GL_NEAREST);
stop_glerror();
}
for (U32 i = 0; i < mTex.size(); ++i)
{
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i,
LLTexUnit::getInternalType(mUsage), mTex[i], 0);
stop_glerror();
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, GL_RENDERBUFFER, mSampleBuffer->mTex[i]);
stop_glerror();
}
}
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
}
@ -467,37 +469,36 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0,
llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
}
if (mSampleBuffer)
if (mask == GL_DEPTH_BUFFER_BIT && source.mStencil != mStencil)
{
mSampleBuffer->copyContents(source, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, source.mFBO);
check_framebuffer_status();
gGL.getTexUnit(0)->bind(this, true);
stop_glerror();
glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1);
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
stop_glerror();
}
else
{
if (mask == GL_DEPTH_BUFFER_BIT && source.mStencil != mStencil)
{
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, source.mFBO);
gGL.getTexUnit(0)->bind(this, true);
stop_glerror();
glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1);
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
stop_glerror();
}
else
{
glBindFramebuffer(GL_READ_FRAMEBUFFER, source.mFBO);
stop_glerror();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFBO);
stop_glerror();
check_framebuffer_status();
stop_glerror();
glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
stop_glerror();
}
glBindFramebuffer(GL_READ_FRAMEBUFFER, source.mFBO);
stop_glerror();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFBO);
stop_glerror();
check_framebuffer_status();
stop_glerror();
glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
stop_glerror();
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
stop_glerror();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
stop_glerror();
}
}
@ -540,179 +541,3 @@ void LLRenderTarget::getViewport(S32* viewport)
viewport[3] = mResY;
}
//==================================================
// LLMultisampleBuffer implementation
//==================================================
LLMultisampleBuffer::LLMultisampleBuffer()
{
}
LLMultisampleBuffer::~LLMultisampleBuffer()
{
release();
}
void LLMultisampleBuffer::release()
{
if (mFBO)
{
glDeleteFramebuffers(1, (GLuint *) &mFBO);
mFBO = 0;
}
if (mTex.size() > 0)
{
glDeleteRenderbuffers(mTex.size(), (GLuint *) &mTex[0]);
mTex.clear();
}
if (mDepth)
{
glDeleteRenderbuffers(1, (GLuint *) &mDepth);
mDepth = 0;
}
}
void LLMultisampleBuffer::bindTarget()
{
bindTarget(this);
}
void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref)
{
if (!ref)
{
ref = this;
}
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
if (gGLManager.mHasDrawBuffers)
{ //setup multiple render targets
GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3};
glDrawBuffersARB(ref->mTex.size(), drawbuffers);
}
check_framebuffer_status();
glViewport(0, 0, mResX, mResY);
sBoundTarget = this;
}
void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo )
{
allocate(resx,resy,color_fmt,depth,stencil,usage,use_fbo,2);
}
void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, U32 samples )
{
stop_glerror();
mResX = resx;
mResY = resy;
mUsage = usage;
mUseDepth = depth;
mStencil = stencil;
release();
mSamples = samples;
if (mSamples <= 1)
{
llerrs << "Cannot create a multisample buffer with less than 2 samples." << llendl;
}
stop_glerror();
if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
{
if (depth)
{
stop_glerror();
allocateDepth();
stop_glerror();
}
glGenFramebuffers(1, (GLuint *) &mFBO);
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
if (mDepth)
{
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth);
if (mStencil)
{
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth);
}
}
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
stop_glerror();
}
addColorAttachment(color_fmt);
}
void LLMultisampleBuffer::addColorAttachment(U32 color_fmt)
{
if (color_fmt == 0)
{
return;
}
U32 offset = mTex.size();
if (offset >= 4 ||
(offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers)))
{
llerrs << "Too many color attachments!" << llendl;
}
U32 tex;
glGenRenderbuffers(1, &tex);
glBindRenderbuffer(GL_RENDERBUFFER, tex);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, color_fmt, mResX, mResY);
stop_glerror();
if (mFBO)
{
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset, GL_RENDERBUFFER, tex);
stop_glerror();
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch (status)
{
case GL_FRAMEBUFFER_COMPLETE:
break;
default:
llerrs << "WTF? " << std::hex << status << llendl;
break;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
mTex.push_back(tex);
}
void LLMultisampleBuffer::allocateDepth()
{
glGenRenderbuffers(1, (GLuint* ) &mDepth);
glBindRenderbuffer(GL_RENDERBUFFER, mDepth);
if (mStencil)
{
glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, GL_DEPTH24_STENCIL8, mResX, mResY);
}
else
{
glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, GL_DEPTH_COMPONENT16, mResX, mResY);
}
}

View File

@ -71,10 +71,7 @@ public:
//allocate resources for rendering
//must be called before use
//multiple calls will release previously allocated resources
void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = FALSE);
//provide this render target with a multisample resource.
void setSampleBuffer(LLMultisampleBuffer* buffer);
void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = false, S32 samples = 0);
//add color buffer attachment
//limit of 4 color attachments per render target
@ -141,7 +138,6 @@ public:
static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; }
protected:
friend class LLMultisampleBuffer;
U32 mResX;
U32 mResY;
std::vector<U32> mTex;
@ -152,26 +148,8 @@ protected:
bool mRenderDepth;
LLTexUnit::eTextureType mUsage;
U32 mSamples;
LLMultisampleBuffer* mSampleBuffer;
static LLRenderTarget* sBoundTarget;
};
class LLMultisampleBuffer : public LLRenderTarget
{
public:
LLMultisampleBuffer();
virtual ~LLMultisampleBuffer();
virtual void release();
virtual void bindTarget();
void bindTarget(LLRenderTarget* ref);
virtual void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo);
void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, U32 samples);
virtual void addColorAttachment(U32 color_fmt);
virtual void allocateDepth();
static LLRenderTarget* sBoundTarget;
};
#endif //!LL_MESA_HEADLESS

View File

@ -209,17 +209,39 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
if (features->hasWaterFog)
{
if (!shader->attachObject("lighting/lightWaterF.glsl"))
if (features->disableTextureIndex)
{
return FALSE;
if (!shader->attachObject("lighting/lightWaterNonIndexedF.glsl"))
{
return FALSE;
}
}
else
{
if (!shader->attachObject("lighting/lightWaterF.glsl"))
{
return FALSE;
}
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
}
}
else
{
if (!shader->attachObject("lighting/lightF.glsl"))
if (features->disableTextureIndex)
{
return FALSE;
if (!shader->attachObject("lighting/lightNonIndexedF.glsl"))
{
return FALSE;
}
}
else
{
if (!shader->attachObject("lighting/lightF.glsl"))
{
return FALSE;
}
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
}
}
}
@ -230,32 +252,76 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
if (features->isShiny && features->hasWaterFog)
{
if (!shader->attachObject("lighting/lightFullbrightShinyWaterF.glsl"))
if (features->disableTextureIndex)
{
return FALSE;
if (!shader->attachObject("lighting/lightFullbrightShinyWaterNonIndexedF.glsl"))
{
return FALSE;
}
}
else
{
if (!shader->attachObject("lighting/lightFullbrightShinyWaterF.glsl"))
{
return FALSE;
}
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
}
}
else if (features->hasWaterFog)
{
if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl"))
if (features->disableTextureIndex)
{
return FALSE;
if (!shader->attachObject("lighting/lightFullbrightWaterNonIndexedF.glsl"))
{
return FALSE;
}
}
else
{
if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl"))
{
return FALSE;
}
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
}
}
else if (features->isShiny)
{
if (!shader->attachObject("lighting/lightFullbrightShinyF.glsl"))
if (features->disableTextureIndex)
{
return FALSE;
if (!shader->attachObject("lighting/lightFullbrightShinyNonIndexedF.glsl"))
{
return FALSE;
}
}
else
{
if (!shader->attachObject("lighting/lightFullbrightShinyF.glsl"))
{
return FALSE;
}
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
}
}
else
{
if (!shader->attachObject("lighting/lightFullbrightF.glsl"))
if (features->disableTextureIndex)
{
return FALSE;
if (!shader->attachObject("lighting/lightFullbrightNonIndexedF.glsl"))
{
return FALSE;
}
}
else
{
if (!shader->attachObject("lighting/lightFullbrightF.glsl"))
{
return FALSE;
}
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
}
}
}
@ -266,17 +332,39 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
if (features->hasWaterFog)
{
if (!shader->attachObject("lighting/lightShinyWaterF.glsl"))
if (features->disableTextureIndex)
{
return FALSE;
if (!shader->attachObject("lighting/lightShinyWaterNonIndexedF.glsl"))
{
return FALSE;
}
}
else
{
if (!shader->attachObject("lighting/lightShinyWaterF.glsl"))
{
return FALSE;
}
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
}
}
else
{
if (!shader->attachObject("lighting/lightShinyF.glsl"))
if (features->disableTextureIndex)
{
return FALSE;
if (!shader->attachObject("lighting/lightShinyNonIndexedF.glsl"))
{
return FALSE;
}
}
else
{
if (!shader->attachObject("lighting/lightShinyF.glsl"))
{
return FALSE;
}
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
}
}
}
@ -315,12 +403,12 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
}
else
{
LL_INFOS("ShaderLoading") << log << LL_ENDL;
LL_DEBUGS("ShaderLoading") << log << LL_ENDL;
}
}
}
GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type)
GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels)
{
GLenum error = GL_NO_ERROR;
if (gDebugGL)
@ -374,6 +462,106 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
GLcharARB* text[1024];
GLuint count = 0;
if (gGLManager.mGLVersion < 3.f)
{
//set version to 1.20
text[count++] = strdup("#version 120\n");
}
else
{ //set version to 1.30
text[count++] = strdup("#version 130\n");
}
//copy preprocessor definitions into buffer
for (std::map<std::string,std::string>::iterator iter = mDefinitions.begin(); iter != mDefinitions.end(); ++iter)
{
std::string define = "#define " + iter->first + " " + iter->second + "\n";
text[count++] = (GLcharARB *) strdup(define.c_str());
}
if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER_ARB)
{
//use specified number of texture channels for indexed texture rendering
/* prepend shader code that looks like this:
uniform sampler2D tex0;
uniform sampler2D tex1;
uniform sampler2D tex2;
.
.
.
uniform sampler2D texN;
varying float vary_texture_index;
vec4 diffuseLookup(vec2 texcoord)
{
switch (int(vary_texture_index+0.25))
{
case 0: return texture2D(tex0, texcoord);
case 1: return texture2D(tex1, texcoord);
case 2: return texture2D(tex2, texcoord);
.
.
.
case N: return texture2D(texN, texcoord);
}
return vec4(0,0,0,0);
}
*/
//uniform declartion
for (S32 i = 0; i < texture_index_channels; ++i)
{
std::string decl = llformat("uniform sampler2D tex%d;\n", i);
text[count++] = strdup(decl.c_str());
}
text[count++] = strdup("varying float vary_texture_index;\n");
text[count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n");
text[count++] = strdup("{\n");
if (gGLManager.mGLVersion >= 3.f)
{
text[count++] = strdup("\tswitch (int(vary_texture_index+0.25))\n");
text[count++] = strdup("\t{\n");
//switch body
for (S32 i = 0; i < texture_index_channels; ++i)
{
std::string case_str = llformat("\t\tcase %d: return texture2D(tex%d, texcoord);\n", i, i);
text[count++] = strdup(case_str.c_str());
}
text[count++] = strdup("\t}\n");
}
else
{
//switches aren't supported, make block that looks like:
/*
int ti = int(vary_texture_index+0.25);
if (ti == 0) return texture2D(tex0, texcoord);
if (ti == 1) return texture2D(tex1, texcoord);
.
.
.
if (ti == N) return texture2D(texN, texcoord);
*/
text[count++] = strdup("int ti = int(vary_texture_index+0.25);\n");
for (S32 i = 0; i < texture_index_channels; ++i)
{
std::string if_str = llformat("if (ti == %d) return texture2D(tex%d, texcoord);\n", i, i);
text[count++] = strdup(if_str.c_str());
}
}
text[count++] = strdup("\treturn vec4(0,0,0,0);\n");
text[count++] = strdup("}\n");
}
//copy file into memory
while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(buff) )
@ -457,7 +645,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (shader_level > 1)
{
shader_level--;
return loadShaderFile(filename,shader_level,type);
return loadShaderFile(filename,shader_level,type,texture_index_channels);
}
LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;
}

View File

@ -43,7 +43,7 @@ public:
void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE);
BOOL linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);
BOOL validateProgramObject(GLhandleARB obj);
GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type);
GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels = -1);
// Implemented in the application to actually point to the shader directory.
virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual
@ -60,6 +60,9 @@ public:
std::vector<std::string> mReservedUniforms;
//preprocessor definitions (name/value)
std::map<std::string, std::string> mDefinitions;
protected:
// our parameter manager singleton instance

View File

@ -934,8 +934,26 @@ void LLVertexBuffer::allocateClientIndexBuffer()
}
}
bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
{
S32 end = index+count;
S32 region_end = region.mIndex+region.mCount;
if (end < region.mIndex ||
index > region_end)
{ //gap exists, do not merge
return false;
}
S32 new_end = llmax(end, region_end);
S32 new_index = llmin(index, region.mIndex);
region.mIndex = new_index;
region.mCount = new_end-new_index;
return true;
}
// Map for data access
U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access)
U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)
{
LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
if (mFinal)
@ -947,8 +965,45 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access)
llerrs << "LLVertexBuffer::mapVertexBuffer() called on unallocated buffer." << llendl;
}
if (!mVertexLocked && useVBOs())
if (useVBOs())
{
if (sDisableVBOMapping || gGLManager.mHasMapBufferRange)
{
if (count == -1)
{
count = mNumVerts-index;
}
bool mapped = false;
//see if range is already mapped
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
{
MappedRegion& region = mMappedVertexRegions[i];
if (region.mType == type)
{
if (expand_region(region, index, count))
{
mapped = true;
break;
}
}
}
if (!mapped)
{
//not already mapped, map new region
MappedRegion region(type, !sDisableVBOMapping && map_range ? -1 : index, count);
mMappedVertexRegions.push_back(region);
}
}
if (mVertexLocked && map_range)
{
llerrs << "Attempted to map a specific range of a buffer that was already mapped." << llendl;
}
if (!mVertexLocked)
{
LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES);
setBuffer(0, type);
@ -957,61 +1012,95 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access)
if(sDisableVBOMapping)
{
map_range = false;
allocateClientVertexBuffer() ;
}
else
{
U8* src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
U8* src = NULL;
#ifdef GL_ARB_map_buffer_range
if (gGLManager.mHasMapBufferRange)
{
if (map_range)
{
S32 offset = mOffsets[type] + sTypeSize[type]*index;
S32 length = (sTypeSize[type]*count+0xF) & ~0xF;
src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, offset, length, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
}
else
{
src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
}
}
else
#else
llassert_always(!gGLManager.mHasMapBufferRange);
#endif
{
map_range = false;
src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
mMappedData = LL_NEXT_ALIGNED_ADDRESS<U8>(src);
mAlignedOffset = mMappedData - src;
stop_glerror();
}
}
if (!mMappedData)
{
log_glerror();
if (!mMappedData)
{
log_glerror();
//check the availability of memory
U32 avail_phy_mem, avail_vir_mem;
LLMemoryInfo::getAvailableMemoryKB(avail_phy_mem, avail_vir_mem) ;
llinfos << "Available physical mwmory(KB): " << avail_phy_mem << llendl ;
llinfos << "Available virtual memory(KB): " << avail_vir_mem << llendl;
//check the availability of memory
U32 avail_phy_mem, avail_vir_mem;
LLMemoryInfo::getAvailableMemoryKB(avail_phy_mem, avail_vir_mem) ;
llinfos << "Available physical mwmory(KB): " << avail_phy_mem << llendl ;
llinfos << "Available virtual memory(KB): " << avail_vir_mem << llendl;
if(!sDisableVBOMapping)
{
//--------------------
//print out more debug info before crash
llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
GLint size ;
glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ;
llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ;
//--------------------
if(!sDisableVBOMapping)
{
//--------------------
//print out more debug info before crash
llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
GLint size ;
glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ;
llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ;
//--------------------
GLint buff;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
if ((GLuint)buff != mGLBuffer)
{
llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
}
GLint buff;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
if ((GLuint)buff != mGLBuffer)
{
llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
}
llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
}
else
{
llerrs << "memory allocation for vertex data failed." << llendl ;
llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
}
else
{
llerrs << "memory allocation for vertex data failed." << llendl ;
}
}
sMappedCount++;
}
sMappedCount++;
}
else
{
map_range = false;
}
return mMappedData;
if (map_range && !sDisableVBOMapping)
{
return mMappedData;
}
else
{
return mMappedData+mOffsets[type]+sTypeSize[type]*index;
}
}
U8* LLVertexBuffer::mapIndexBuffer(S32 access)
U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
{
LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
if (mFinal)
@ -1023,8 +1112,41 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 access)
llerrs << "LLVertexBuffer::mapIndexBuffer() called on unallocated buffer." << llendl;
}
if (!mIndexLocked && useVBOs())
if (useVBOs())
{
if (sDisableVBOMapping || gGLManager.mHasMapBufferRange)
{
if (count == -1)
{
count = mNumIndices-index;
}
bool mapped = false;
//see if range is already mapped
for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
{
MappedRegion& region = mMappedIndexRegions[i];
if (expand_region(region, index, count))
{
mapped = true;
break;
}
}
if (!mapped)
{
//not already mapped, map new region
MappedRegion region(TYPE_INDEX, !sDisableVBOMapping && map_range ? -1 : index, count);
mMappedIndexRegions.push_back(region);
}
}
if (mIndexLocked && map_range)
{
llerrs << "Attempted to map a specific range of a buffer that was already mapped." << llendl;
}
if (!mIndexLocked)
{
LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);
@ -1034,12 +1156,36 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 access)
if(sDisableVBOMapping)
{
map_range = false;
allocateClientIndexBuffer() ;
}
else
{
U8* src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
mMappedIndexData = LL_NEXT_ALIGNED_ADDRESS<U8>(src);
U8* src = NULL;
#ifdef GL_ARB_map_buffer_range
if (gGLManager.mHasMapBufferRange)
{
if (map_range)
{
S32 offset = sizeof(U16)*index;
S32 length = sizeof(U16)*count;
src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
}
else
{
src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, sizeof(U16)*mNumIndices, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
}
}
else
#else
llassert_always(!gGLManager.mHasMapBufferRange);
#endif
{
map_range = false;
src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
mMappedIndexData = src; //LL_NEXT_ALIGNED_ADDRESS<U8>(src);
mAlignedIndexOffset = mMappedIndexData - src;
stop_glerror();
}
@ -1068,31 +1214,81 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 access)
sMappedCount++;
}
else
{
map_range = false;
}
return mMappedIndexData ;
if (map_range && !sDisableVBOMapping)
{
return mMappedIndexData;
}
else
{
return mMappedIndexData + sizeof(U16)*index;
}
}
void LLVertexBuffer::unmapBuffer(S32 type)
{
LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER);
if (!useVBOs())
if (!useVBOs() || type == -2)
{
return ; //nothing to unmap
}
bool updated_all = false ;
if (mMappedData && mVertexLocked && type != TYPE_INDEX)
{
updated_all = (mIndexLocked && type < 0) ; //both vertex and index buffers done updating
if(sDisableVBOMapping)
{
stop_glerror();
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData);
stop_glerror();
if (!mMappedVertexRegions.empty())
{
stop_glerror();
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
{
const MappedRegion& region = mMappedVertexRegions[i];
S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0;
S32 length = sTypeSize[region.mType]*region.mCount;
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, mMappedData+offset);
stop_glerror();
}
mMappedVertexRegions.clear();
}
else
{
stop_glerror();
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData);
stop_glerror();
}
}
else
{
#ifdef GL_ARB_map_buffer_range
if (gGLManager.mHasMapBufferRange)
{
if (!mMappedVertexRegions.empty())
{
stop_glerror();
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
{
const MappedRegion& region = mMappedVertexRegions[i];
S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0;
S32 length = sTypeSize[region.mType]*region.mCount;
glFlushMappedBufferRange(GL_ARRAY_BUFFER_ARB, offset, length);
stop_glerror();
}
mMappedVertexRegions.clear();
}
}
#else
llassert_always(!gGLManager.mHasMapBufferRange);
#endif
stop_glerror();
glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
stop_glerror();
@ -1103,17 +1299,53 @@ void LLVertexBuffer::unmapBuffer(S32 type)
mVertexLocked = FALSE ;
sMappedCount--;
}
if(mMappedIndexData && mIndexLocked && (type < 0 || type == TYPE_INDEX))
if (mMappedIndexData && mIndexLocked && (type < 0 || type == TYPE_INDEX))
{
if(sDisableVBOMapping)
{
stop_glerror();
glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData);
stop_glerror();
if (!mMappedIndexRegions.empty())
{
for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
{
const MappedRegion& region = mMappedIndexRegions[i];
S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
S32 length = sizeof(U16)*region.mCount;
glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, mMappedIndexData+offset);
stop_glerror();
}
mMappedIndexRegions.clear();
}
else
{
stop_glerror();
glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData);
stop_glerror();
}
}
else
{
#ifdef GL_ARB_map_buffer_range
if (gGLManager.mHasMapBufferRange)
{
if (!mMappedIndexRegions.empty())
{
for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
{
const MappedRegion& region = mMappedIndexRegions[i];
S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
S32 length = sizeof(U16)*region.mCount;
glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
stop_glerror();
}
mMappedIndexRegions.clear();
}
}
#else
llassert_always(!gGLManager.mHasMapBufferRange);
#endif
stop_glerror();
glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
stop_glerror();
@ -1152,19 +1384,19 @@ template <class T,S32 type> struct VertexBufferStrider
typedef LLStrider<T> strider_t;
static bool get(LLVertexBuffer& vbo,
strider_t& strider,
S32 index)
S32 index, S32 count, bool map_range)
{
if (type == LLVertexBuffer::TYPE_INDEX)
{
S32 stride = sizeof(T);
U8* ptr = vbo.mapIndexBuffer(index, count, map_range);
if (vbo.mapIndexBuffer() == NULL)
if (ptr == NULL)
{
llwarns << "mapIndexBuffer failed!" << llendl;
return FALSE;
}
strider = (T*)(vbo.getMappedIndices() + index*stride);
strider = (T*)ptr;
strider.setStride(0);
return TRUE;
}
@ -1172,13 +1404,15 @@ template <class T,S32 type> struct VertexBufferStrider
{
S32 stride = LLVertexBuffer::sTypeSize[type];
if (vbo.mapVertexBuffer(type) == NULL)
U8* ptr = vbo.mapVertexBuffer(type, index, count, map_range);
if (ptr == NULL)
{
llwarns << "mapVertexBuffer failed!" << llendl;
return FALSE;
}
strider = (T*)(vbo.getMappedData() + vbo.getOffset(type)+index*stride);
strider = (T*)ptr;
strider.setStride(stride);
return TRUE;
}
@ -1190,55 +1424,48 @@ template <class T,S32 type> struct VertexBufferStrider
}
};
bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector3>& strider, S32 index)
bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<LLVector3,TYPE_VERTEX>::get(*this, strider, index);
return VertexBufferStrider<LLVector3,TYPE_VERTEX>::get(*this, strider, index, count, map_range);
}
bool LLVertexBuffer::getIndexStrider(LLStrider<U16>& strider, S32 index)
bool LLVertexBuffer::getIndexStrider(LLStrider<U16>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<U16,TYPE_INDEX>::get(*this, strider, index);
return VertexBufferStrider<U16,TYPE_INDEX>::get(*this, strider, index, count, map_range);
}
bool LLVertexBuffer::getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index)
bool LLVertexBuffer::getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD0>::get(*this, strider, index);
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD0>::get(*this, strider, index, count, map_range);
}
bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index)
bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index);
}
/*bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index)
{
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index);
}
bool LLVertexBuffer::getTexCoord3Strider(LLStrider<LLVector2>& strider, S32 index)
{
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD3>::get(*this, strider, index);
}*/
bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index)
{
return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index);
}
bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index)
{
return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index);
}
bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index)
{
return VertexBufferStrider<LLColor4U,TYPE_COLOR>::get(*this, strider, index);
}
bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, S32 index)
{
return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index);
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index, count, map_range);
}
bool LLVertexBuffer::getWeight4Strider(LLStrider<LLVector4>& strider, S32 index)
bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<LLVector4,TYPE_WEIGHT4>::get(*this, strider, index);
return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count, map_range);
}
bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index, count, map_range);
}
bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<LLColor4U,TYPE_COLOR>::get(*this, strider, index, count, map_range);
}
bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index, count, map_range);
}
bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index)
bool LLVertexBuffer::getWeight4Strider(LLStrider<LLVector4>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index);
return VertexBufferStrider<LLVector4,TYPE_WEIGHT4>::get(*this, strider, index, count, map_range);
}
bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index, count, map_range);
}
//----------------------------------------------------------------------------
@ -1497,17 +1724,16 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
}
if (data_mask & MAP_VERTEX)
{
glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
if (data_mask & MAP_TEXTURE_INDEX)
{
glVertexPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
}
else
{
glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
}
}
llglassertok();
}
void LLVertexBuffer::markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count)
{
// TODO: use GL_APPLE_flush_buffer_range here
/*if (useVBOs() && !mFilthy)
{
}*/
}

View File

@ -77,6 +77,18 @@ protected:
class LLVertexBuffer : public LLRefCount
{
public:
class MappedRegion
{
public:
S32 mType;
S32 mIndex;
S32 mCount;
MappedRegion(S32 type, S32 index, S32 count)
: mType(type), mIndex(index), mCount(count)
{ }
};
LLVertexBuffer(const LLVertexBuffer& rhs)
{
*this = rhs;
@ -130,6 +142,9 @@ public:
TYPE_CLOTHWEIGHT,
TYPE_MAX,
TYPE_INDEX,
//no actual additional data, but indicates position.w is texture index
TYPE_TEXTURE_INDEX,
};
enum {
MAP_VERTEX = (1<<TYPE_VERTEX),
@ -144,6 +159,7 @@ public:
MAP_WEIGHT = (1<<TYPE_WEIGHT),
MAP_WEIGHT4 = (1<<TYPE_WEIGHT4),
MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT),
MAP_TEXTURE_INDEX = (1<<TYPE_TEXTURE_INDEX),
};
protected:
@ -173,8 +189,8 @@ public:
LLVertexBuffer(U32 typemask, S32 usage);
// map for data access
U8* mapVertexBuffer(S32 type = -1, S32 access = -1);
U8* mapIndexBuffer(S32 access = -1);
U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range);
U8* mapIndexBuffer(S32 index, S32 count, bool map_range);
// set for rendering
virtual void setBuffer(U32 data_mask, S32 type = -1); // calls setupVertexBuffer() if data_mask is not 0
@ -189,16 +205,16 @@ public:
// vb->getNormalStrider(norms);
// setVertsNorms(verts, norms);
// vb->unmapBuffer();
bool getVertexStrider(LLStrider<LLVector3>& strider, S32 index=0);
bool getIndexStrider(LLStrider<U16>& strider, S32 index=0);
bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0);
bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0);
bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0);
bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0);
bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0);
bool getWeightStrider(LLStrider<F32>& strider, S32 index=0);
bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0);
bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0);
bool getVertexStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getIndexStrider(LLStrider<U16>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getWeightStrider(LLStrider<F32>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
BOOL isEmpty() const { return mEmpty; }
BOOL isLocked() const { return mVertexLocked || mIndexLocked; }
@ -218,8 +234,6 @@ public:
S32 getOffset(S32 type) const { return mOffsets[type]; }
S32 getUsage() const { return mUsage; }
void markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count);
void draw(U32 mode, U32 count, U32 indices_offset) const;
void drawArrays(U32 mode, U32 offset, U32 count) const;
void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const;
@ -253,20 +267,8 @@ protected:
BOOL mDynamicSize; // if TRUE, buffer has been resized at least once (and should be padded)
S32 mOffsets[TYPE_MAX];
class DirtyRegion
{
public:
U32 mIndex;
U32 mCount;
U32 mIndicesIndex;
U32 mIndicesCount;
DirtyRegion(U32 vi, U32 vc, U32 ii, U32 ic)
: mIndex(vi), mCount(vc), mIndicesIndex(ii), mIndicesCount(ic)
{ }
};
std::vector<DirtyRegion> mDirtyRegions; //vector of dirty regions to rebuild
std::vector<MappedRegion> mMappedVertexRegions;
std::vector<MappedRegion> mMappedIndexRegions;
public:
static S32 sCount;

View File

@ -28,6 +28,8 @@ include_directories(
set(llui_SOURCE_FILES
llaccordionctrl.cpp
llaccordionctrltab.cpp
llbadge.cpp
llbadgeowner.cpp
llbutton.cpp
llcheckboxctrl.cpp
llclipboard.cpp
@ -119,6 +121,8 @@ set(llui_HEADER_FILES
llaccordionctrl.h
llaccordionctrltab.h
llbadge.h
llbadgeowner.h
llbutton.h
llcallbackmap.h
llcheckboxctrl.h
@ -245,11 +249,11 @@ target_link_libraries(llui
)
# Add tests
if (LL_TESTS)
include(LLAddBuildTest)
SET(llui_TEST_SOURCE_FILES
llurlmatch.cpp
llurlentry.cpp
)
LL_ADD_PROJECT_UNIT_TESTS(llui "${llui_TEST_SOURCE_FILES}")
endif (LL_TESTS)
if(LL_TESTS)
include(LLAddBuildTest)
SET(llui_TEST_SOURCE_FILES
llurlmatch.cpp
llurlentry.cpp
)
LL_ADD_PROJECT_UNIT_TESTS(llui "${llui_TEST_SOURCE_FILES}")
endif(LL_TESTS)

View File

@ -1022,7 +1022,7 @@ void LLAccordionCtrlTab::updateLayout ( const LLRect& child_rect )
S32 panel_width = child_rect.getWidth();
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
if(mScrollbar->getVisible() != false)
if(mScrollbar && mScrollbar->getVisible() != false)
{
panel_top+=mScrollbar->getDocPos();
panel_width-=scrollbar_size;

274
indra/llui/llbadge.cpp Normal file
View File

@ -0,0 +1,274 @@
/**
* @file llbadge.cpp
* @brief Implementation for badges
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#define LLBADGE_CPP
#include "llbadge.h"
#include "lluictrlfactory.h"
static LLDefaultChildRegistry::Register<LLBadge> r("badge");
// Compiler optimization, generate extern template
template class LLBadge* LLView::getChild<class LLBadge>(const std::string& name, BOOL recurse) const;
LLBadge::Params::Params()
: image("image")
, border_image("border_image")
, border_color("border_color")
, image_color("image_color")
, label("label")
, label_color("label_color")
, location("location", LLRelPos::TOP_LEFT)
, location_percent_hcenter("location_percent_hcenter")
, location_percent_vcenter("location_percent_vcenter")
, padding_horiz("padding_horiz")
, padding_vert("padding_vert")
{
// We set a name here so the name isn't necessary in any xml files that use badges
name = "badge";
}
bool LLBadge::Params::equals(const Params& a) const
{
bool comp = true;
// skip owner in comparison on purpose
comp &= (border_image() == a.border_image());
comp &= (border_color() == a.border_color());
comp &= (image() == a.image());
comp &= (image_color() == a.image_color());
comp &= (label() == a.label());
comp &= (label_color() == a.label_color());
comp &= (location() == a.location());
comp &= (location_percent_hcenter() == a.location_percent_hcenter());
comp &= (location_percent_vcenter() == a.location_percent_vcenter());
comp &= (padding_horiz() == a.padding_horiz());
comp &= (padding_vert() == a.padding_vert());
return comp;
}
LLBadge::LLBadge(const LLBadge::Params& p)
: LLUICtrl(p)
, mOwner(p.owner)
, mBorderImage(p.border_image)
, mBorderColor(p.border_color)
, mGLFont(p.font)
, mImage(p.image)
, mImageColor(p.image_color)
, mLabel(p.label)
, mLabelColor(p.label_color)
, mLocation(p.location)
, mLocationPercentHCenter(0.5f)
, mLocationPercentVCenter(0.5f)
, mPaddingHoriz(p.padding_horiz)
, mPaddingVert(p.padding_vert)
{
if (mImage.isNull())
{
llwarns << "Badge: " << getName() << " with no image!" << llendl;
}
//
// The following logic is to set the mLocationPercentHCenter and mLocationPercentVCenter
// based on the Location enum and our horizontal and vertical location percentages. The
// draw code then uses this on the owner rectangle to compute the screen location for
// the badge.
//
if (!LLRelPos::IsCenter(mLocation))
{
F32 h_center = p.location_percent_hcenter * 0.01f;
F32 v_center = p.location_percent_vcenter * 0.01f;
if (LLRelPos::IsRight(mLocation))
{
mLocationPercentHCenter = 0.5f * (1.0f + h_center);
}
else if (LLRelPos::IsLeft(mLocation))
{
mLocationPercentHCenter = 0.5f * (1.0f - h_center);
}
if (LLRelPos::IsTop(mLocation))
{
mLocationPercentVCenter = 0.5f * (1.0f + v_center);
}
else if (LLRelPos::IsBottom(mLocation))
{
mLocationPercentVCenter = 0.5f * (1.0f - v_center);
}
}
}
LLBadge::~LLBadge()
{
}
void LLBadge::setLabel(const LLStringExplicit& label)
{
mLabel = label;
}
//
// This is a fallback function to render a rectangle for badges without a valid image
//
void renderBadgeBackground(F32 centerX, F32 centerY, F32 width, F32 height, const LLColor4U &color)
{
gGL.pushUIMatrix();
gGL.loadUIIdentity();
gGL.setSceneBlendType(LLRender::BT_REPLACE);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.color4ubv(color.mV);
gGL.texCoord2i(0, 0);
F32 x = LLFontGL::sCurOrigin.mX + centerX - width * 0.5f;
F32 y = LLFontGL::sCurOrigin.mY + centerY - height * 0.5f;
LLRectf screen_rect(llround(x),
llround(y),
llround(x) + width,
llround(y) + height);
LLVector3 vertices[4];
vertices[0] = LLVector3(screen_rect.mRight, screen_rect.mTop, 1.0f);
vertices[1] = LLVector3(screen_rect.mLeft, screen_rect.mTop, 1.0f);
vertices[2] = LLVector3(screen_rect.mLeft, screen_rect.mBottom, 1.0f);
vertices[3] = LLVector3(screen_rect.mRight, screen_rect.mBottom, 1.0f);
gGL.begin(LLRender::QUADS);
{
gGL.vertexBatchPreTransformed(vertices, 4);
}
gGL.end();
gGL.popUIMatrix();
}
// virtual
void LLBadge::draw()
{
if (!mLabel.empty())
{
LLView* owner_view = mOwner.get();
if (owner_view)
{
//
// Calculate badge position based on owner
//
LLRect owner_rect;
owner_view->localRectToOtherView(owner_view->getLocalRect(), & owner_rect, this);
F32 badge_center_x = owner_rect.mLeft + owner_rect.getWidth() * mLocationPercentHCenter;
F32 badge_center_y = owner_rect.mBottom + owner_rect.getHeight() * mLocationPercentVCenter;
//
// Calculate badge size based on label text
//
LLWString badge_label_wstring = mLabel;
S32 badge_label_begin_offset = 0;
S32 badge_char_length = S32_MAX;
S32 badge_pixel_length = S32_MAX;
F32 *right_position_out = NULL;
BOOL do_not_use_ellipses = false;
F32 badge_width = (2.0f * mPaddingHoriz) +
mGLFont->getWidthF32(badge_label_wstring.c_str(), badge_label_begin_offset, badge_char_length);
F32 badge_height = (2.0f * mPaddingVert) + mGLFont->getLineHeight();
//
// Draw button image, if available.
// Otherwise draw basic rectangular button.
//
F32 alpha = getDrawContext().mAlpha;
if (!mImage.isNull())
{
F32 badge_x = badge_center_x - badge_width * 0.5f;
F32 badge_y = badge_center_y - badge_height * 0.5f;
mImage->drawSolid((S32) badge_x, (S32) badge_y, (S32) badge_width, (S32) badge_height, mImageColor % alpha);
if (!mBorderImage.isNull())
{
mBorderImage->drawSolid((S32) badge_x, (S32) badge_y, (S32) badge_width, (S32) badge_height, mBorderColor % alpha);
}
}
else
{
lldebugs << "No image for badge " << getName() << " on owner " << owner_view->getName() << llendl;
renderBadgeBackground(badge_center_x, badge_center_y,
badge_width, badge_height,
mImageColor % alpha);
}
//
// Draw the label
//
mGLFont->render(badge_label_wstring, badge_label_begin_offset,
badge_center_x, badge_center_y,
mLabelColor % alpha,
LLFontGL::HCENTER, LLFontGL::VCENTER, // centered around the position
LLFontGL::NORMAL, // normal text (not bold, italics, etc.)
LLFontGL::DROP_SHADOW_SOFT,
badge_char_length, badge_pixel_length,
right_position_out, do_not_use_ellipses);
}
}
}
namespace LLInitParam
{
void TypeValues<LLRelPos::Location>::declareValues()
{
declare("bottom", LLRelPos::BOTTOM);
declare("bottom_left", LLRelPos::BOTTOM_LEFT);
declare("bottom_right", LLRelPos::BOTTOM_RIGHT);
declare("center", LLRelPos::CENTER);
declare("left", LLRelPos::LEFT);
declare("right", LLRelPos::RIGHT);
declare("top", LLRelPos::TOP);
declare("top_left", LLRelPos::TOP_LEFT);
declare("top_right", LLRelPos::TOP_RIGHT);
}
}
// eof

159
indra/llui/llbadge.h Normal file
View File

@ -0,0 +1,159 @@
/**
* @file llbadge.h
* @brief Header for badges
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLBADGE_H
#define LL_LLBADGE_H
#include <string>
#include "lluicolor.h"
#include "lluictrl.h"
#include "llstring.h"
#include "lluiimage.h"
#include "llview.h"
//
// Declarations
//
class LLUICtrlFactory;
class LLFontGL;
//
// Relative Position Alignment
//
namespace LLRelPos
{
enum Location
{
CENTER = 0,
LEFT = (1 << 0),
RIGHT = (1 << 1),
TOP = (1 << 2),
BOTTOM = (1 << 3),
BOTTOM_LEFT = (BOTTOM | LEFT),
BOTTOM_RIGHT = (BOTTOM | RIGHT),
TOP_LEFT = (TOP | LEFT),
TOP_RIGHT = (TOP | RIGHT),
};
inline bool IsBottom(Location relPos) { return (relPos & BOTTOM) == BOTTOM; }
inline bool IsCenter(Location relPos) { return (relPos == CENTER); }
inline bool IsLeft(Location relPos) { return (relPos & LEFT) == LEFT; }
inline bool IsRight(Location relPos) { return (relPos & RIGHT) == RIGHT; }
inline bool IsTop(Location relPos) { return (relPos & TOP) == TOP; }
}
// NOTE: This needs to occur before Optional<LLRelPos::Location> declaration for proper compilation.
namespace LLInitParam
{
template<>
struct TypeValues<LLRelPos::Location> : public TypeValuesHelper<LLRelPos::Location>
{
static void declareValues();
};
}
//
// Classes
//
class LLBadge
: public LLUICtrl
{
public:
struct Params
: public LLInitParam::Block<Params, LLUICtrl::Params>
{
Optional< LLHandle<LLView> > owner; // Mandatory in code but not in xml
Optional< LLUIImage* > border_image;
Optional< LLUIColor > border_color;
Optional< LLUIImage* > image;
Optional< LLUIColor > image_color;
Optional< std::string > label;
Optional< LLUIColor > label_color;
Optional< LLRelPos::Location > location;
Optional< U32 > location_percent_hcenter;
Optional< U32 > location_percent_vcenter;
Optional< F32 > padding_horiz;
Optional< F32 > padding_vert;
Params();
bool equals(const Params&) const;
};
protected:
friend class LLUICtrlFactory;
LLBadge(const Params& p);
public:
~LLBadge();
virtual void draw();
const std::string getLabel() const { return wstring_to_utf8str(mLabel); }
void setLabel( const LLStringExplicit& label);
private:
LLPointer< LLUIImage > mBorderImage;
LLUIColor mBorderColor;
const LLFontGL* mGLFont;
LLPointer< LLUIImage > mImage;
LLUIColor mImageColor;
LLUIString mLabel;
LLUIColor mLabelColor;
LLRelPos::Location mLocation;
F32 mLocationPercentHCenter;
F32 mLocationPercentVCenter;
LLHandle< LLView > mOwner;
F32 mPaddingHoriz;
F32 mPaddingVert;
};
// Build time optimization, generate once in .cpp file
#ifndef LLBADGE_CPP
extern template class LLBadge* LLView::getChild<class LLBadge>(const std::string& name, BOOL recurse) const;
#endif
#endif // LL_LLBADGE_H

118
indra/llui/llbadgeowner.cpp Normal file
View File

@ -0,0 +1,118 @@
/**
* @file llbadgeowner.cpp
* @brief Class to manage badges attached to a UI control
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llbadgeowner.h"
#include "llpanel.h"
//
// Classes
//
LLBadgeOwner::LLBadgeOwner(LLHandle< LLView > viewHandle)
: mBadge(NULL)
, mBadgeOwnerView(viewHandle)
{
}
void LLBadgeOwner::initBadgeParams(const LLBadge::Params& p)
{
if (!p.equals(LLUICtrlFactory::getDefaultParams<LLBadge>()))
{
mBadge = createBadge(p);
}
}
void LLBadgeOwner::setBadgeLabel(const LLStringExplicit& label)
{
if (mBadge == NULL)
{
mBadge = createBadge(LLUICtrlFactory::getDefaultParams<LLBadge>());
addBadgeToParentPanel();
}
if (mBadge)
{
mBadge->setLabel(label);
//
// Push the badge to the front so it renders on top
//
LLView * parent = mBadge->getParent();
if (parent)
{
parent->sendChildToFront(mBadge);
}
}
}
void LLBadgeOwner::addBadgeToParentPanel()
{
LLView * owner_view = mBadgeOwnerView.get();
if (mBadge && owner_view)
{
// Badge parent is badge owner by default
LLView * badge_parent = owner_view;
// Find the appropriate parent for the badge
LLView * parent = owner_view->getParent();
while (parent)
{
LLPanel * parent_panel = dynamic_cast<LLPanel *>(parent);
if (parent_panel && parent_panel->acceptsBadge())
{
badge_parent = parent;
break;
}
parent = parent->getParent();
}
if (badge_parent)
{
badge_parent->addChild(mBadge);
}
else
{
llwarns << "Unable to find parent panel for badge " << mBadge->getName() << " on " << owner_view->getName() << llendl;
}
}
}
LLBadge* LLBadgeOwner::createBadge(const LLBadge::Params& p)
{
LLBadge::Params badge_params(p);
badge_params.owner = mBadgeOwnerView;
return LLUICtrlFactory::create<LLBadge>(badge_params);
}

58
indra/llui/llbadgeowner.h Normal file
View File

@ -0,0 +1,58 @@
/**
* @file llbadgeowner.h
* @brief Header for badge owners
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLBADGEOWNER_H
#define LL_LLBADGEOWNER_H
#include "llbadge.h"
#include "llview.h"
//
// Classes
//
class LLBadgeOwner
{
public:
LLBadgeOwner(LLHandle< LLView > viewHandle);
void initBadgeParams(const LLBadge::Params& p);
void addBadgeToParentPanel();
void setBadgeLabel(const LLStringExplicit& label);
private:
LLBadge* createBadge(const LLBadge::Params& p);
private:
LLBadge* mBadge;
LLHandle< LLView > mBadgeOwnerView;
};
#endif // LL_LLBADGEOWNER_H

View File

@ -99,7 +99,9 @@ LLButton::Params::Params()
scale_image("scale_image", true),
hover_glow_amount("hover_glow_amount"),
commit_on_return("commit_on_return", true),
use_draw_context_alpha("use_draw_context_alpha", true)
use_draw_context_alpha("use_draw_context_alpha", true),
badge("badge"),
handle_right_mouse("handle_right_mouse")
{
addSynonym(is_toggle, "toggle");
held_down_delay.seconds = 0.5f;
@ -109,6 +111,7 @@ LLButton::Params::Params()
LLButton::LLButton(const LLButton::Params& p)
: LLUICtrl(p),
LLBadgeOwner(LLView::getHandle()),
mMouseDownFrame(0),
mMouseHeldDownCount(0),
mBorderEnabled( FALSE ),
@ -160,8 +163,8 @@ LLButton::LLButton(const LLButton::Params& p)
mMouseDownSignal(NULL),
mMouseUpSignal(NULL),
mHeldDownSignal(NULL),
mUseDrawContextAlpha(p.use_draw_context_alpha)
mUseDrawContextAlpha(p.use_draw_context_alpha),
mHandleRightMouse(p.handle_right_mouse)
{
static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);
static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>());
@ -244,6 +247,11 @@ LLButton::LLButton(const LLButton::Params& p)
{
setHeldDownCallback(initCommitCallback(p.mouse_held_callback));
}
if (p.badge.isProvided())
{
LLBadgeOwner::initBadgeParams(p.badge());
}
}
LLButton::~LLButton()
@ -327,8 +335,12 @@ boost::signals2::connection LLButton::setHeldDownCallback( button_callback_t cb,
BOOL LLButton::postBuild()
{
autoResize();
return TRUE;
addBadgeToParentPanel();
return LLUICtrl::postBuild();
}
BOOL LLButton::handleUnicodeCharHere(llwchar uni_char)
{
BOOL handled = FALSE;
@ -447,7 +459,7 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)
BOOL LLButton::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
if (!childrenHandleRightMouseDown(x, y, mask))
if (mHandleRightMouse && !childrenHandleRightMouseDown(x, y, mask))
{
// Route future Mouse messages here preemptively. (Release on mouse up.)
gFocusMgr.setMouseCapture( this );
@ -460,37 +472,42 @@ BOOL LLButton::handleRightMouseDown(S32 x, S32 y, MASK mask)
// if (pointInView(x, y))
// {
// }
// send the mouse down signal
LLUICtrl::handleRightMouseDown(x,y,mask);
// *TODO: Return result of LLUICtrl call above? Should defer to base class
// but this might change the mouse handling of existing buttons in a bad way
// if they are not mouse opaque.
}
// send the mouse down signal
LLUICtrl::handleRightMouseDown(x,y,mask);
// *TODO: Return result of LLUICtrl call above? Should defer to base class
// but this might change the mouse handling of existing buttons in a bad way
// if they are not mouse opaque.
return TRUE;
}
BOOL LLButton::handleRightMouseUp(S32 x, S32 y, MASK mask)
{
// We only handle the click if the click both started and ended within us
if( hasMouseCapture() )
if (mHandleRightMouse)
{
// Always release the mouse
gFocusMgr.setMouseCapture( NULL );
// We only handle the click if the click both started and ended within us
if( hasMouseCapture() )
{
// Always release the mouse
gFocusMgr.setMouseCapture( NULL );
// if (pointInView(x, y))
// {
// mRightMouseUpSignal(this, x,y,mask);
// }
// if (pointInView(x, y))
// {
// mRightMouseUpSignal(this, x,y,mask);
// }
}
else
{
childrenHandleRightMouseUp(x, y, mask);
}
// send the mouse up signal
LLUICtrl::handleRightMouseUp(x,y,mask);
// *TODO: Return result of LLUICtrl call above? Should defer to base class
// but this might change the mouse handling of existing buttons in a bad way.
// if they are not mouse opaque.
}
else
{
childrenHandleRightMouseUp(x, y, mask);
}
// send the mouse up signal
LLUICtrl::handleRightMouseUp(x,y,mask);
// *TODO: Return result of LLUICtrl call above? Should defer to base class
// but this might change the mouse handling of existing buttons in a bad way.
// if they are not mouse opaque.
return TRUE;
}

View File

@ -27,6 +27,8 @@
#ifndef LL_LLBUTTON_H
#define LL_LLBUTTON_H
#include "lluuid.h"
#include "llbadgeowner.h"
#include "llcontrol.h"
#include "lluictrl.h"
#include "v4color.h"
@ -52,15 +54,13 @@ S32 round_up(S32 grid, S32 value);
class LLUICtrlFactory;
class LLUIImage;
class LLUUID;
//
// Classes
//
class LLButton
: public LLUICtrl
: public LLUICtrl, public LLBadgeOwner
{
public:
struct Params
@ -125,7 +125,11 @@ public:
Optional<F32> hover_glow_amount;
Optional<TimeIntervalParam> held_down_delay;
Optional<bool> use_draw_context_alpha;
Optional<bool> use_draw_context_alpha;
Optional<LLBadge::Params> badge;
Optional<bool> handle_right_mouse;
Params();
};
@ -249,7 +253,7 @@ public:
void setImageDisabledSelected(LLPointer<LLUIImage> image);
void setImageFlash(LLPointer<LLUIImage> image);
void setImagePressed(LLPointer<LLUIImage> image);
void setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; }
BOOL getCommitOnReturn() const { return mCommitOnReturn; }
@ -357,6 +361,8 @@ private:
bool mForcePressedState;
LLFrameTimer mFlashingTimer;
bool mHandleRightMouse;
};
// Build time optimization, generate once in .cpp file

View File

@ -49,6 +49,8 @@ void LLLayoutStack::OrientationNames::declareValues()
//
LLLayoutPanel::LLLayoutPanel(const Params& p)
: LLPanel(p),
mExpandedMinDimSpecified(false),
mExpandedMinDim(p.min_dim),
mMinDim(p.min_dim),
mMaxDim(p.max_dim),
mAutoResize(p.auto_resize),
@ -58,6 +60,13 @@ LLLayoutPanel::LLLayoutPanel(const Params& p)
mVisibleAmt(1.f), // default to fully visible
mResizeBar(NULL)
{
// Set the expanded min dim if it is provided, otherwise it gets the p.min_dim value
if (p.expanded_min_dim.isProvided())
{
mExpandedMinDimSpecified = true;
mExpandedMinDim = p.expanded_min_dim();
}
// panels initialized as hidden should not start out partially visible
if (!getVisible())
{
@ -78,20 +87,20 @@ LLLayoutPanel::~LLLayoutPanel()
delete mResizeBar;
mResizeBar = NULL;
}
F32 LLLayoutPanel::getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation)
{
if (orientation == LLLayoutStack::HORIZONTAL)
{
F32 collapse_amt =
clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)mMinDim / (F32)llmax(1, getRect().getWidth()));
clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, getRelevantMinDim() / (F32)llmax(1, getRect().getWidth()));
return mVisibleAmt * collapse_amt;
}
else
{
F32 collapse_amt =
clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, llmin(1.f, (F32)mMinDim / (F32)llmax(1, getRect().getHeight())));
return mVisibleAmt * collapse_amt;
F32 collapse_amt =
clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, llmin(1.f, getRelevantMinDim() / (F32)llmax(1, getRect().getHeight())));
return mVisibleAmt * collapse_amt;
}
}
@ -182,14 +191,14 @@ BOOL LLLayoutStack::postBuild()
}
bool LLLayoutStack::addChild(LLView* child, S32 tab_group)
{
{
LLLayoutPanel* panelp = dynamic_cast<LLLayoutPanel*>(child);
if (panelp)
{
if (panelp)
{
mPanels.push_back(panelp);
}
}
return LLView::addChild(child, tab_group);
}
}
S32 LLLayoutStack::getDefaultHeight(S32 cur_height)
@ -281,9 +290,9 @@ bool LLLayoutStack::getPanelMinSize(const std::string& panel_name, S32* min_dimp
{
LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name);
if (panel)
if (panel && min_dimp)
{
if (min_dimp) *min_dimp = panel->mMinDim;
*min_dimp = panel->getRelevantMinDim();
}
return NULL != panel;
@ -316,7 +325,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
e_panel_list_t::iterator panel_it;
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
LLPanel* panelp = (*panel_it);
LLLayoutPanel* panelp = (*panel_it);
if (panelp->getVisible())
{
if (mAnimate)
@ -366,9 +375,9 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
if (mOrientation == HORIZONTAL)
{
// enforce minimize size constraint by default
if (panelp->getRect().getWidth() < (*panel_it)->mMinDim)
if (panelp->getRect().getWidth() < (*panel_it)->getRelevantMinDim())
{
panelp->reshape((*panel_it)->mMinDim, panelp->getRect().getHeight());
panelp->reshape((*panel_it)->getRelevantMinDim(), panelp->getRect().getHeight());
}
total_width += llround(panelp->getRect().getWidth() * (*panel_it)->getCollapseFactor(mOrientation));
// want n-1 panel gaps for n panels
@ -380,9 +389,9 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
else //VERTICAL
{
// enforce minimize size constraint by default
if (panelp->getRect().getHeight() < (*panel_it)->mMinDim)
if (panelp->getRect().getHeight() < (*panel_it)->getRelevantMinDim())
{
panelp->reshape(panelp->getRect().getWidth(), (*panel_it)->mMinDim);
panelp->reshape(panelp->getRect().getWidth(), (*panel_it)->getRelevantMinDim());
}
total_height += llround(panelp->getRect().getHeight() * (*panel_it)->getCollapseFactor(mOrientation));
if (panel_it != mPanels.begin())
@ -409,28 +418,20 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
|| (!(*panel_it)->mAutoResize
&& !force_resize))
{
if (mOrientation == HORIZONTAL)
{
shrink_headroom_total += (*panel_it)->getRect().getWidth() - (*panel_it)->mMinDim;
}
else //VERTICAL
{
shrink_headroom_total += (*panel_it)->getRect().getHeight() - (*panel_it)->mMinDim;
}
S32 relevant_dimension = (mOrientation == HORIZONTAL) ? (*panel_it)->getRect().getWidth() : (*panel_it)->getRect().getHeight();
F32 relevant_min = ((*panel_it)->mCollapsed ? (*panel_it)->getRelevantMinDim() : (*panel_it)->mExpandedMinDim);
shrink_headroom_total += relevant_dimension - relevant_min;
}
else
{
num_resizable_panels++;
if (mOrientation == HORIZONTAL)
{
shrink_headroom_available += (*panel_it)->getRect().getWidth() - (*panel_it)->mMinDim;
shrink_headroom_total += (*panel_it)->getRect().getWidth() - (*panel_it)->mMinDim;
}
else //VERTICAL
{
shrink_headroom_available += (*panel_it)->getRect().getHeight() - (*panel_it)->mMinDim;
shrink_headroom_total += (*panel_it)->getRect().getHeight() - (*panel_it)->mMinDim;
}
S32 relevant_dimension = (mOrientation == HORIZONTAL) ? (*panel_it)->getRect().getWidth() : (*panel_it)->getRect().getHeight();
F32 relevant_min = ((*panel_it)->mCollapsed ? (*panel_it)->getRelevantMinDim() : (*panel_it)->mExpandedMinDim);
shrink_headroom_available += relevant_dimension - relevant_min;
shrink_headroom_total += relevant_dimension - relevant_min;
}
}
@ -452,27 +453,28 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
LLPanel* panelp = (*panel_it);
LLLayoutPanel* panelp = (*panel_it);
S32 cur_width = panelp->getRect().getWidth();
S32 cur_height = panelp->getRect().getHeight();
S32 new_width = cur_width;
S32 new_height = cur_height;
S32 new_height = cur_height;
S32 relevant_min = (S32) panelp->getRelevantMinDim();
if (mOrientation == HORIZONTAL)
{
new_width = llmax((*panel_it)->mMinDim, new_width);
new_width = llmax(relevant_min, new_width);
}
else
{
new_height = llmax((*panel_it)->mMinDim, new_height);
new_height = llmax(relevant_min, new_height);
}
S32 delta_size = 0;
// if panel can automatically resize (not animating, and resize flag set)...
if ((*panel_it)->getCollapseFactor(mOrientation) == 1.f
&& (force_resize || (*panel_it)->mAutoResize)
&& !(*panel_it)->mResizeBar->hasMouseCapture())
if (panelp->getCollapseFactor(mOrientation) == 1.f
&& (force_resize || panelp->mAutoResize)
&& !panelp->mResizeBar->hasMouseCapture())
{
if (mOrientation == HORIZONTAL)
{
@ -481,8 +483,8 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
{
// shrink proportionally to amount over minimum
// so we can do this in one pass
delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_width - (*panel_it)->mMinDim) / (F32)shrink_headroom_available)) : 0;
shrink_headroom_available -= (cur_width - (*panel_it)->mMinDim);
delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_width - panelp->getRelevantMinDim()) / (F32)shrink_headroom_available)) : 0;
shrink_headroom_available -= (cur_width - relevant_min);
}
else
{
@ -491,7 +493,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
num_resizable_panels--;
}
pixels_to_distribute -= delta_size;
new_width = llmax((*panel_it)->mMinDim, cur_width + delta_size);
new_width = llmax(relevant_min, cur_width + delta_size);
}
else
{
@ -504,8 +506,8 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
{
// shrink proportionally to amount over minimum
// so we can do this in one pass
delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_height - (*panel_it)->mMinDim) / (F32)shrink_headroom_available)) : 0;
shrink_headroom_available -= (cur_height - (*panel_it)->mMinDim);
delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_height - relevant_min) / (F32)shrink_headroom_available)) : 0;
shrink_headroom_available -= (cur_height - relevant_min);
}
else
{
@ -513,7 +515,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
num_resizable_panels--;
}
pixels_to_distribute -= delta_size;
new_height = llmax((*panel_it)->mMinDim, cur_height + delta_size);
new_height = llmax(relevant_min, cur_height + delta_size);
}
else
{
@ -566,19 +568,20 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
LLLayoutPanel* last_resizeable_panel = NULL;
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
LLPanel* panelp = (*panel_it);
LLLayoutPanel* panelp = (*panel_it);
F32 relevant_min = panelp->getRelevantMinDim();
if (mOrientation == HORIZONTAL)
{
(*panel_it)->mResizeBar->setResizeLimits(
(*panel_it)->mMinDim,
(*panel_it)->mMinDim + shrink_headroom_total);
relevant_min,
relevant_min + shrink_headroom_total);
}
else //VERTICAL
{
(*panel_it)->mResizeBar->setResizeLimits(
(*panel_it)->mMinDim,
(*panel_it)->mMinDim + shrink_headroom_total);
relevant_min,
relevant_min + shrink_headroom_total);
}
// toggle resize bars based on panel visibility, resizability, etc
@ -658,7 +661,7 @@ void LLLayoutStack::calcMinExtents()
{
if (mOrientation == HORIZONTAL)
{
mMinWidth += (*panel_it)->mMinDim;
mMinWidth += (*panel_it)->getRelevantMinDim();
if (panel_it != mPanels.begin())
{
mMinWidth += mPanelSpacing;
@ -666,7 +669,7 @@ void LLLayoutStack::calcMinExtents()
}
else //VERTICAL
{
mMinHeight += (*panel_it)->mMinDim;
mMinHeight += (*panel_it)->getRelevantMinDim();
if (panel_it != mPanels.begin())
{
mMinHeight += mPanelSpacing;

View File

@ -30,10 +30,10 @@
#include "llpanel.h"
class LLPanel;
class LLLayoutPanel;
class LLLayoutStack : public LLView, public LLInstanceTracker<LLLayoutStack>
{
public:
@ -149,6 +149,7 @@ private:
F32 mCloseTimeConstant;
}; // end class LLLayoutStack
class LLLayoutPanel : public LLPanel
{
friend class LLLayoutStack;
@ -156,13 +157,15 @@ friend class LLUICtrlFactory;
public:
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{
Optional<S32> min_dim,
Optional<S32> expanded_min_dim,
min_dim,
max_dim;
Optional<bool> user_resize,
auto_resize;
Params()
: min_dim("min_dim", 0),
: expanded_min_dim("expanded_min_dim", 0),
min_dim("min_dim", 0),
max_dim("max_dim", 0),
user_resize("user_resize", true),
auto_resize("auto_resize", true)
@ -177,15 +180,36 @@ public:
~LLLayoutPanel();
void initFromParams(const Params& p);
void setMinDim(S32 value) { mMinDim = value; }
S32 getMinDim() const { return mMinDim; }
void setMinDim(S32 value) { mMinDim = value; if (!mExpandedMinDimSpecified) mExpandedMinDim = value; }
S32 getMaxDim() const { return mMaxDim; }
void setMaxDim(S32 value) { mMaxDim = value; }
protected:
LLLayoutPanel(const Params& p) ;
S32 getExpandedMinDim() const { return mExpandedMinDim; }
void setExpandedMinDim(S32 value) { mExpandedMinDim = value; mExpandedMinDimSpecified = true; }
S32 getRelevantMinDim() const
{
S32 min_dim = mMinDim;
if (!mCollapsed)
{
min_dim = mExpandedMinDim;
}
return min_dim;
}
protected:
LLLayoutPanel(const Params& p);
F32 getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation);
bool mExpandedMinDimSpecified;
S32 mExpandedMinDim;
S32 mMinDim;
S32 mMaxDim;
BOOL mAutoResize;

View File

@ -86,6 +86,8 @@ public:
*/
void start();
void reset() { mCurImageIdx = 0; }
private:
LLLoadingIndicator(const Params&);
void initFromParams(const Params&);

View File

@ -87,7 +87,8 @@ LLPanel::Params::Params()
filename("filename"),
class_name("class"),
help_topic("help_topic"),
visible_callback("visible_callback")
visible_callback("visible_callback"),
accepts_badge("accepts_badge")
{
name = "panel";
addSynonym(background_visible, "bg_visible");
@ -113,7 +114,8 @@ LLPanel::LLPanel(const LLPanel::Params& p)
mCommitCallbackRegistrar(false),
mEnableCallbackRegistrar(false),
mXMLFilename(p.filename),
mVisibleSignal(NULL)
mVisibleSignal(NULL),
mAcceptsBadge(p.accepts_badge)
// *NOTE: Be sure to also change LLPanel::initFromParams(). We have too
// many classes derived from LLPanel to retrofit them all to pass in params.
{
@ -485,6 +487,8 @@ void LLPanel::initFromParams(const LLPanel::Params& p)
mBgAlphaImage = p.bg_alpha_image();
mBgOpaqueImageOverlay = p.bg_opaque_image_overlay;
mBgAlphaImageOverlay = p.bg_alpha_image_overlay;
mAcceptsBadge = p.accepts_badge;
}
static LLFastTimer::DeclareTimer FTM_PANEL_SETUP("Panel Setup");

View File

@ -89,6 +89,8 @@ public:
Multiple<LocalizedString> strings;
Optional<CommitCallbackParam> visible_callback;
Optional<bool> accepts_badge;
Params();
};
@ -250,6 +252,8 @@ public:
boost::signals2::connection setVisibleCallback( const commit_signal_t::slot_type& cb );
bool acceptsBadge() const { return mAcceptsBadge; }
protected:
// Override to set not found list
LLButton* getDefaultButton() { return mDefaultBtn; }
@ -264,6 +268,7 @@ protected:
static factory_stack_t sFactoryStack;
private:
bool mAcceptsBadge;
BOOL mBgVisible; // any background at all?
BOOL mBgOpaque; // use opaque color or image
LLUIColor mBgOpaqueColor;

View File

@ -337,7 +337,7 @@ LLLocale::LLLocale(const std::string& locale_string)
char* new_locale_string = setlocale( LC_ALL, locale_string.c_str());
if ( new_locale_string == NULL)
{
llwarns << "Failed to set locale " << locale_string << llendl;
LL_WARNS_ONCE("LLLocale") << "Failed to set locale " << locale_string << LL_ENDL;
setlocale(LC_ALL, SYSTEM_LOCALE.c_str());
}
//else

View File

@ -52,6 +52,7 @@ LLSpinCtrl::Params::Params()
: label_width("label_width"),
decimal_digits("decimal_digits"),
allow_text_entry("allow_text_entry", true),
label_wrap("label_wrap", false),
text_enabled_color("text_enabled_color"),
text_disabled_color("text_disabled_color"),
up_button("up_button"),
@ -80,6 +81,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
{
LLRect label_rect( 0, centered_top, label_width, centered_bottom );
LLTextBox::Params params;
params.wrap(p.label_wrap);
params.name("SpinCtrl Label");
params.rect(label_rect);
params.initial_value(p.label());

View File

@ -44,6 +44,7 @@ public:
Optional<S32> label_width;
Optional<U32> decimal_digits;
Optional<bool> allow_text_entry;
Optional<bool> label_wrap;
Optional<LLUIColor> text_enabled_color;
Optional<LLUIColor> text_disabled_color;

View File

@ -68,6 +68,7 @@ LLUICtrl::ControlVisibility::ControlVisibility()
LLUICtrl::Params::Params()
: tab_stop("tab_stop", true),
chrome("chrome", false),
requests_front("requests_front", false),
label("label"),
initial_value("value"),
init_callback("init_callback"),
@ -96,9 +97,10 @@ const LLUICtrl::Params& LLUICtrl::getDefaultParams()
LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel)
: LLView(p),
mTentative(FALSE),
mIsChrome(FALSE),
mRequestsFront(p.requests_front),
mTabStop(FALSE),
mTentative(FALSE),
mViewModel(viewmodel),
mControlVariable(NULL),
mEnabledControlVariable(NULL),
@ -123,6 +125,8 @@ void LLUICtrl::initFromParams(const Params& p)
{
LLView::initFromParams(p);
mRequestsFront = p.requests_front;
setIsChrome(p.chrome);
setControlName(p.control_name);
if(p.enabled_controls.isProvided())
@ -403,6 +407,36 @@ LLViewModel* LLUICtrl::getViewModel() const
return mViewModel;
}
//virtual
BOOL LLUICtrl::postBuild()
{
//
// Find all of the children that want to be in front and move them to the front
//
if (getChildCount() > 0)
{
std::vector<LLUICtrl*> childrenToMoveToFront;
for (LLView::child_list_const_iter_t child_it = beginChild(); child_it != endChild(); ++child_it)
{
LLUICtrl* uictrl = dynamic_cast<LLUICtrl*>(*child_it);
if (uictrl && uictrl->mRequestsFront)
{
childrenToMoveToFront.push_back(uictrl);
}
}
for (std::vector<LLUICtrl*>::iterator it = childrenToMoveToFront.begin(); it != childrenToMoveToFront.end(); ++it)
{
sendChildToFront(*it);
}
}
return LLView::postBuild();
}
bool LLUICtrl::setControlValue(const LLSD& value)
{
if (mControlVariable)

View File

@ -94,7 +94,8 @@ public:
{
Optional<std::string> label;
Optional<bool> tab_stop,
chrome;
chrome,
requests_front;
Optional<LLSD> initial_value;
Optional<CommitCallbackParam> init_callback,
@ -143,6 +144,8 @@ protected:
virtual LLViewModel* getViewModel() const;
// We shouldn't ever need to set this directly
//virtual void setViewModel(const LLViewModelPtr&);
virtual BOOL postBuild();
public:
// LLView interface
@ -301,8 +304,9 @@ protected:
private:
BOOL mTabStop;
BOOL mIsChrome;
BOOL mRequestsFront;
BOOL mTabStop;
BOOL mTentative;
LLRootHandle<LLUICtrl> mUICtrlHandle;

View File

@ -62,11 +62,15 @@ list(APPEND llvfs_SOURCE_FILES ${llvfs_HEADER_FILES})
add_library (llvfs ${llvfs_SOURCE_FILES})
target_link_libraries(llvfs
set(vfs_BOOST_LIBRARIES
${BOOST_FILESYSTEM_LIBRARY}
${BOOST_SYSTEM_LIBRARY}
)
target_link_libraries(llvfs
${vfs_BOOST_LIBRARIES}
)
if (DARWIN)
include(CMakeFindFrameworks)
find_library(CARBON_LIBRARY Carbon)
@ -76,15 +80,21 @@ endif (DARWIN)
# Add tests
if (LL_TESTS)
include(LLAddBuildTest)
# UNIT TESTS
SET(llvfs_TEST_SOURCE_FILES
# none so far
)
LL_ADD_PROJECT_UNIT_TESTS(llvfs "${llvfs_TEST_SOURCE_FILES}")
include(LLAddBuildTest)
# UNIT TESTS
SET(llvfs_TEST_SOURCE_FILES
lldiriterator.cpp
)
# INTEGRATION TESTS
set(test_libs llmath llcommon llvfs ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES})
# TODO: Some of these need refactoring to be proper Unit tests rather than Integration tests.
LL_ADD_INTEGRATION_TEST(lldir "" "${test_libs}")
set_source_files_properties(lldiriterator.cpp
PROPERTIES
LL_TEST_ADDITIONAL_LIBRARIES "${vfs_BOOST_LIBRARIES}"
)
LL_ADD_PROJECT_UNIT_TESTS(llvfs "${llvfs_TEST_SOURCE_FILES}")
# INTEGRATION TESTS
set(test_libs llmath llcommon llvfs ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES})
# TODO: Some of these need refactoring to be proper Unit tests rather than Integration tests.
LL_ADD_INTEGRATION_TEST(lldir "" "${test_libs}")
endif (LL_TESTS)

View File

@ -121,6 +121,14 @@ bool LLDirIterator::Impl::next(std::string &fname)
return found;
}
/**
Converts the incoming glob into a regex. This involves
converting incoming glob expressions to regex equivilents and
at the same time, escaping any regex meaningful characters which
do not have glob meaning, i.e.
.()+|^$
in the input.
*/
std::string glob_to_regex(const std::string& glob)
{
std::string regex;
@ -135,9 +143,6 @@ std::string glob_to_regex(const std::string& glob)
switch (c)
{
case '.':
regex+="\\.";
break;
case '*':
if (glob.begin() == i)
{
@ -170,8 +175,16 @@ std::string glob_to_regex(const std::string& glob)
case '!':
regex+= square_brace_open ? '^' : c;
break;
case '.': // This collection have different regex meaning
case '^': // and so need escaping.
case '(':
case ')':
case '+':
case '|':
case '$':
regex += '\\';
default:
regex+=c;
regex += c;
break;
}

View File

@ -0,0 +1,65 @@
/**
* @file lldiriterator_test.cpp
* @date 2011-06
* @brief LLDirIterator test cases.
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.,
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "../lldiriterator.h"
namespace tut
{
struct LLDirIteratorFixture
{
LLDirIteratorFixture()
{
}
};
typedef test_group<LLDirIteratorFixture> LLDirIteratorTest_factory;
typedef LLDirIteratorTest_factory::object LLDirIteratorTest_t;
LLDirIteratorTest_factory tf("LLDirIterator");
/*
CHOP-662 was originally introduced to deal with crashes deleting files from
a directory (VWR-25500). However, this introduced a crash looking for
old chat logs as the glob_to_regex function in lldiriterator wasn't escaping lots of regexp characters
*/
void test_chop_662(void)
{
// Check a selection of bad group names from the crash reports
LLDirIterator iter(".","+bad-group-name]+??-??.*");
LLDirIterator iter1(".","))--@---bad-group-name2((??-??.*\\.txt");
LLDirIterator iter2(".","__^v--x)Cuide d sua vida(x--v^__??-??.*");
}
template<> template<>
void LLDirIteratorTest_t::test<1>()
{
test_chop_662();
}
}

View File

@ -361,6 +361,8 @@ set(viewer_SOURCE_FILES
llpanellogin.cpp
llpanelloginlistener.cpp
llpanelmaininventory.cpp
llpanelmarketplaceinbox.cpp
llpanelmarketplaceoutbox.cpp
llpanelmediasettingsgeneral.cpp
llpanelmediasettingspermissions.cpp
llpanelmediasettingssecurity.cpp
@ -909,6 +911,8 @@ set(viewer_HEADER_FILES
llpanellogin.h
llpanelloginlistener.h
llpanelmaininventory.h
llpanelmarketplaceinbox.h
llpanelmarketplaceoutbox.h
llpanelmediasettingsgeneral.h
llpanelmediasettingspermissions.h
llpanelmediasettingssecurity.h
@ -1465,7 +1469,7 @@ set(PACKAGE ON CACHE BOOL
"Add a package target that builds an installer package.")
if (WINDOWS)
set_target_properties(${VIEWER_BINARY_NAME}
set_target_properties(${VIEWER_BINARY_NAME}
PROPERTIES
# *TODO -reenable this once we get server usage sorted out
#LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:\"__tcmalloc\""

View File

@ -20,6 +20,7 @@
<key>tags</key>
<array>
<string>AppInit</string>
<string>Capabilities</string>
<string>SystemInfo</string>
<string>TextureCache</string>
<string>AppCache</string>
@ -43,6 +44,7 @@
<array>
<!-- sample entry for debugging a specific item -->
<!-- <string>Voice</string> -->
<string>Capabilities</string>
</array>
</map>
</array>

View File

@ -711,9 +711,9 @@
<key>BrowserEnableJSObject</key>
<map>
<key>Comment</key>
<string>Enable or disable the viewer to Javascript bridge object.</string>
<string>(WARNING: Advanced feature. Use if you are aware of the implications). Enable or disable the viewer to Javascript bridge object.</string>
<key>Persist</key>
<integer>1</integer>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
@ -3058,6 +3058,17 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>EnableGestureSounds</key>
<map>
<key>Comment</key>
<string>Play sounds from gestures</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>EnableMouselook</key>
<map>
<key>Comment</key>
@ -3256,17 +3267,6 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstLoginThisInstall</key>
<map>
<key>Comment</key>
<string>Specifies that you have not successfully logged in since you installed the latest update</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstName</key>
<map>
<key>Comment</key>
@ -4179,6 +4179,28 @@
<string>F32</string>
<key>Value</key>
<real>1.0</real>
</map>
<key>InventoryDisplayInbox</key>
<map>
<key>Comment</key>
<string>Override received items inventory inbox display</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>InventoryDisplayOutbox</key>
<map>
<key>Comment</key>
<string>Override merchant inventory outbox display</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>InventoryLinking</key>
<map>
@ -4422,6 +4444,17 @@
<key>Value</key>
<real>2.0</real>
</map>
<key>LastInventoryInboxExpand</key>
<map>
<key>Comment</key>
<string>The last time the received items inbox was expanded.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string />
</map>
<key>LCDDestination</key>
<map>
<key>Comment</key>
@ -5589,10 +5622,10 @@
<key>Value</key>
<real>0</real>
</map>
<key>MeshUseWholeModelUpload</key>
<key>MeshUploadLogXML</key>
<map>
<key>Comment</key>
<string>Upload model in its entirety instead of mesh-by-mesh (new caps)</string>
<string>Verbose XML logging on mesh upload</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@ -5600,6 +5633,17 @@
<key>Value</key>
<real>0</real>
</map>
<key>MeshUploadFakeErrors</key>
<map>
<key>Comment</key>
<string>Force upload errors (for testing)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<real>0</real>
</map>
<key>MigrateCacheDirectory</key>
<map>
<key>Comment</key>
@ -6557,7 +6601,7 @@
<key>Value</key>
<string>0</string>
</map>
<key>PrecachingDelay</key>
<key>PrecachingDelay</key>
<map>
<key>Comment</key>
<string>Delay when logging in to load world before showing it (seconds)</string>
@ -7123,6 +7167,75 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>OctreeMaxNodeCapacity</key>
<map>
<key>Comment</key>
<string>Maximum number of elements to store in a single octree node</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>128</integer>
</map>
<key>OctreeStaticObjectSizeFactor</key>
<map>
<key>Comment</key>
<string>Multiplier on static object size for determining octree node size </string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>4</integer>
</map>
<key>OctreeAlphaDistanceFactor</key>
<map>
<key>Comment</key>
<string>Multiplier on alpha object distance for determining octree node size </string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Vector3</string>
<key>Value</key>
<array>
<real>0.1</real>
<real>0.0</real>
<real>0.0</real>
</array>
</map>
<key>OctreeAttachmentSizeFactor</key>
<map>
<key>Comment</key>
<string>Multiplier on attachment size for determining octree node size </string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>4</integer>
</map>
<key>OctreeDistanceFactor</key>
<map>
<key>Comment</key>
<string>Multiplier on distance for determining octree node size </string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Vector3</string>
<key>Value</key>
<array>
<real>0.01</real>
<real>0.0</real>
<real>0.0</real>
</array>
</map>
<key>RenderAnisotropic</key>
<map>
<key>Comment</key>
@ -7220,7 +7333,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
<integer>1.0</integer>
<real>1.0</real>
</map>
<key>RenderAvatarVP</key>
<map>
@ -7476,6 +7589,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>RenderMaxTextureIndex</key>
<map>
<key>Comment</key>
<string>Maximum texture index to use for indexed texture rendering.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>6</integer>
</map>
<key>RenderDebugTextureBind</key>
<map>
<key>Comment</key>
@ -8621,7 +8745,7 @@
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>8192</integer>
<integer>65536</integer>
</map>
<key>RenderMaxVBOSize</key>
<map>
@ -8889,17 +9013,6 @@
<integer>0</integer>
</map>
<key>RenderUseTriStrips</key>
<map>
<key>Comment</key>
<string>Use triangle strips for rendering prims.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>RenderUseTriStrips</key>
<map>
<key>Comment</key>
<string>Use triangle strips for rendering prims.</string>
@ -8974,7 +9087,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
<integer>0</integer>
</map>
<key>RenderUseStreamVBO</key>
<map>
@ -9084,7 +9197,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>3.0</real>
<real>2.0</real>
</map>
<key>MeshThreadCount</key>
<map>
@ -9680,6 +9793,17 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>NearbyListShowMap</key>
<map>
<key>Comment</key>
<string>Show/hide map above nearby people list</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>NearbyListShowIcons</key>
<map>
<key>Comment</key>
@ -12427,7 +12551,7 @@
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>-1</integer>
<integer>20</integer>
</map>
<key>WaterEditPresets</key>
<map>

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
void default_lighting();

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
attribute vec4 weight; //1

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
mat4 getSkinnedTransform();

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
void default_lighting();

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol);
void calcAtmospherics(vec3 inPositionEye);

View File

@ -5,7 +5,7 @@
* $License$
*/
#version 120
attribute vec4 object_weight;

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
uniform sampler2D diffuseMap;

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
mat4 getSkinnedTransform();

View File

@ -5,13 +5,14 @@
* $/LicenseInfo$
*/
#version 120
#extension GL_ARB_texture_rectangle : enable
uniform sampler2D diffuseMap;
uniform sampler2DRect depthMap;
vec4 diffuseLookup(vec2 texcoord);
uniform mat4 shadow_matrix[6];
uniform vec4 shadow_clip;
uniform vec2 screen_res;
@ -47,7 +48,7 @@ void main()
vec4 pos = vec4(vary_position, 1.0);
vec4 diff= texture2D(diffuseMap, gl_TexCoord[0].xy);
vec4 diff= diffuseLookup(gl_TexCoord[0].xy);
vec4 col = vec4(vary_ambient + vary_directional.rgb, gl_Color.a);
vec4 color = diff * col;

View File

@ -0,0 +1,67 @@
/**
* @file alphaF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* $/LicenseInfo$
*/
#extension GL_ARB_texture_rectangle : enable
uniform sampler2DRect depthMap;
uniform sampler2D diffuseMap;
uniform mat4 shadow_matrix[6];
uniform vec4 shadow_clip;
uniform vec2 screen_res;
vec3 atmosLighting(vec3 light);
vec3 scaleSoftClip(vec3 light);
varying vec3 vary_ambient;
varying vec3 vary_directional;
varying vec3 vary_fragcoord;
varying vec3 vary_position;
varying vec3 vary_pointlight_col;
uniform mat4 inv_proj;
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).a;
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
void main()
{
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
frag *= screen_res;
vec4 pos = vec4(vary_position, 1.0);
vec4 diff= texture2D(diffuseMap,gl_TexCoord[0].xy);
vec4 col = vec4(vary_ambient + vary_directional.rgb, gl_Color.a);
vec4 color = diff * col;
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
color.rgb += diff.rgb * vary_pointlight_col.rgb;
gl_FragColor = color;
//gl_FragColor = vec4(1,0,1,1);
//gl_FragColor = vec4(1,0,1,1)*shadow;
}

View File

@ -5,7 +5,7 @@
* $License$
*/
#version 120
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
mat4 getObjectSkinnedTransform();

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
void calcAtmospherics(vec3 inPositionEye);
@ -23,6 +23,7 @@ varying vec3 vary_fragcoord;
varying vec3 vary_position;
varying vec3 vary_light;
varying vec3 vary_pointlight_col;
varying float vary_texture_index;
uniform float near_clip;
uniform float shadow_offset;
@ -61,11 +62,13 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
void main()
{
//transform vertex
gl_Position = ftransform();
vec4 vert = vec4(gl_Vertex.xyz, 1.0);
vary_texture_index = gl_Vertex.w;
gl_Position = gl_ModelViewProjectionMatrix * vert;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
vec4 pos = (gl_ModelViewMatrix * gl_Vertex);
vec4 pos = (gl_ModelViewMatrix * vert);
vec3 norm = normalize(gl_NormalMatrix * gl_Normal);
float dp_directional_light = max(0.0, dot(norm, gl_LightSource[0].position.xyz));
@ -102,7 +105,7 @@ void main()
gl_FogFragCoord = pos.z;
pos = gl_ModelViewProjectionMatrix * gl_Vertex;
pos = gl_ModelViewProjectionMatrix * vert;
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
}

View File

@ -5,7 +5,7 @@
* $License$
*/
#version 120
uniform sampler2D diffuseMap;

View File

@ -5,7 +5,7 @@
* $License$
*/
#version 120
mat4 getObjectSkinnedTransform();

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
mat4 getSkinnedTransform();

View File

@ -0,0 +1,21 @@
/**
* @file avatarEyesV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* $/LicenseInfo$
*/
varying vec3 vary_normal;
void main()
{
//transform vertex
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
vary_normal = normalize(gl_NormalMatrix * gl_Normal);
gl_FrontColor = gl_Color;
}

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
uniform sampler2D diffuseMap;

View File

@ -5,14 +5,17 @@
* $/LicenseInfo$
*/
#version 120
uniform sampler2D diffuseMap;
varying vec4 post_pos;
void main()
{
//gl_FragColor = vec4(1,1,1,gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy).a);
gl_FragColor = vec4(1,1,1,1);
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
}

View File

@ -5,12 +5,14 @@
* $/LicenseInfo$
*/
#version 120
mat4 getSkinnedTransform();
attribute vec4 weight;
varying vec4 post_pos;
void main()
{
gl_TexCoord[0] = gl_MultiTexCoord0;
@ -30,8 +32,9 @@ void main()
norm = normalize(norm);
pos = gl_ProjectionMatrix * pos;
pos.z = max(pos.z, -pos.w+0.01);
gl_Position = pos;
post_pos = pos;
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
gl_FrontColor = gl_Color;
}

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
mat4 getSkinnedTransform();

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
#extension GL_ARB_texture_rectangle : enable
@ -26,7 +26,7 @@ uniform vec2 screen_res;
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).a;
float depth = texture2DRect(depthMap, pos_screen.xy).r;
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
@ -39,7 +39,7 @@ vec4 getPosition(vec2 pos_screen)
void main()
{
vec2 tc = vary_fragcoord.xy;
vec2 tc = vary_fragcoord.xy;
vec3 norm = texture2DRect(normalMap, tc).xyz;
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
vec3 pos = getPosition(tc).xyz;

View File

@ -0,0 +1,113 @@
/**
* @file blurLightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* $/LicenseInfo$
*/
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_texture_multisample : enable
uniform sampler2DMS depthMap;
uniform sampler2DMS normalMap;
uniform sampler2DRect lightMap;
uniform float dist_factor;
uniform float blur_size;
uniform vec2 delta;
uniform vec3 kern[4];
uniform float kern_scale;
varying vec2 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 screen_res;
vec3 texture2DMS3(sampler2DMS tex, ivec2 tc)
{
vec3 ret = vec3(0,0,0);
for (int i = 0; i < samples; i++)
{
ret += texelFetch(tex, tc, i).rgb;
}
return ret/samples;
}
float texture2DMS1(sampler2DMS tex, ivec2 tc)
{
float ret = 0;
for (int i = 0; i < samples; i++)
{
ret += texelFetch(tex, tc, i).r;
}
return ret/samples;
}
vec4 getPosition(ivec2 pos_screen)
{
float depth = texture2DMS1(depthMap, pos_screen.xy);
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
void main()
{
vec2 tc = vary_fragcoord.xy;
ivec2 itc = ivec2(tc);
vec3 norm = texture2DMS3(normalMap, itc).xyz;
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
vec3 pos = getPosition(itc).xyz;
vec4 ccol = texture2DRect(lightMap, tc).rgba;
vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy);
dlt /= max(-pos.z*dist_factor, 1.0);
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'
vec4 col = defined_weight.xyxx * ccol;
// 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
float pointplanedist_tolerance_pow2 = pos.z*pos.z*0.00005;
// perturb sampling origin slightly in screen-space to hide edge-ghosting artifacts where smoothing radius is quite large
tc += ( (mod(tc.x+tc.y,2) - 0.5) * kern[1].z * dlt * 0.5 );
for (int i = 1; i < 4; i++)
{
vec2 samptc = tc + kern[i].z*dlt;
vec3 samppos = getPosition(ivec2(samptc)).xyz;
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
if (d*d <= pointplanedist_tolerance_pow2)
{
col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
defined_weight += kern[i].xy;
}
}
for (int i = 1; i < 4; i++)
{
vec2 samptc = vec2(tc - kern[i].z*dlt);
vec3 samppos = getPosition(ivec2(samptc)).xyz;
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
if (d*d <= pointplanedist_tolerance_pow2)
{
col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
defined_weight += kern[i].xy;
}
}
col /= defined_weight.xyxx;
col.y *= col.y;
gl_FragColor = col;
}

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
varying vec2 vary_fragcoord;
uniform vec2 screen_res;

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
uniform sampler2D diffuseMap;
uniform sampler2D bumpMap;

View File

@ -5,7 +5,7 @@
* $License$
*/
#version 120
varying vec3 vary_mat0;
varying vec3 vary_mat1;

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
varying vec3 vary_mat0;
varying vec3 vary_mat1;

View File

@ -0,0 +1,79 @@
/**
* @file WLCloudsF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* $/LicenseInfo$
*/
/////////////////////////////////////////////////////////////////////////
// The fragment shader for the sky
/////////////////////////////////////////////////////////////////////////
varying vec4 vary_CloudColorSun;
varying vec4 vary_CloudColorAmbient;
varying float vary_CloudDensity;
uniform sampler2D cloud_noise_texture;
uniform vec4 cloud_pos_density1;
uniform vec4 cloud_pos_density2;
uniform vec4 gamma;
/// Soft clips the light with a gamma correction
vec3 scaleSoftClip(vec3 light) {
//soft clip effect:
light = 1. - clamp(light, vec3(0.), vec3(1.));
light = 1. - pow(light, gamma.xxx);
return light;
}
void main()
{
// Set variables
vec2 uv1 = gl_TexCoord[0].xy;
vec2 uv2 = gl_TexCoord[1].xy;
vec4 cloudColorSun = vary_CloudColorSun;
vec4 cloudColorAmbient = vary_CloudColorAmbient;
float cloudDensity = vary_CloudDensity;
vec2 uv3 = gl_TexCoord[2].xy;
vec2 uv4 = gl_TexCoord[3].xy;
// Offset texture coords
uv1 += cloud_pos_density1.xy; //large texture, visible density
uv2 += cloud_pos_density1.xy; //large texture, self shadow
uv3 += cloud_pos_density2.xy; //small texture, visible density
uv4 += cloud_pos_density2.xy; //small texture, self shadow
// Compute alpha1, the main cloud opacity
float alpha1 = (texture2D(cloud_noise_texture, uv1).x - 0.5) + (texture2D(cloud_noise_texture, uv3).x - 0.5) * cloud_pos_density2.z;
alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10. * cloud_pos_density1.z, 1.);
// And smooth
alpha1 = 1. - alpha1 * alpha1;
alpha1 = 1. - alpha1 * alpha1;
// Compute alpha2, for self shadowing effect
// (1 - alpha2) will later be used as percentage of incoming sunlight
float alpha2 = (texture2D(cloud_noise_texture, uv2).x - 0.5);
alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
// And smooth
alpha2 = 1. - alpha2;
alpha2 = 1. - alpha2 * alpha2;
// Combine
vec4 color;
color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
color *= 2.;
/// Gamma correct for WL (soft clip effect).
gl_FragData[0] = vec4(scaleSoftClip(color.rgb), alpha1);
gl_FragData[1] = vec4(0.0,0.0,0.0,0.0);
gl_FragData[2] = vec4(0,0,1,0);
}

View File

@ -0,0 +1,165 @@
/**
* @file WLCloudsV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* $/LicenseInfo$
*/
//////////////////////////////////////////////////////////////////////////
// The vertex shader for creating the atmospheric sky
///////////////////////////////////////////////////////////////////////////////
// Output parameters
varying vec4 vary_CloudColorSun;
varying vec4 vary_CloudColorAmbient;
varying float vary_CloudDensity;
// Inputs
uniform vec3 camPosLocal;
uniform vec4 lightnorm;
uniform vec4 sunlight_color;
uniform vec4 ambient;
uniform vec4 blue_horizon;
uniform vec4 blue_density;
uniform vec4 haze_horizon;
uniform vec4 haze_density;
uniform vec4 cloud_shadow;
uniform vec4 density_multiplier;
uniform vec4 max_y;
uniform vec4 glow;
uniform vec4 cloud_color;
uniform vec4 cloud_scale;
void main()
{
// World / view / projection
gl_Position = ftransform();
gl_TexCoord[0] = gl_MultiTexCoord0;
// Get relative position
vec3 P = gl_Vertex.xyz - camPosLocal.xyz + vec3(0,50,0);
// Set altitude
if (P.y > 0.)
{
P *= (max_y.x / P.y);
}
else
{
P *= (-32000. / P.y);
}
// Can normalize then
vec3 Pn = normalize(P);
float Plen = length(P);
// Initialize temp variables
vec4 temp1 = vec4(0.);
vec4 temp2 = vec4(0.);
vec4 blue_weight;
vec4 haze_weight;
vec4 sunlight = sunlight_color;
vec4 light_atten;
// Sunlight attenuation effect (hue and brightness) due to atmosphere
// this is used later for sunlight modulation at various altitudes
light_atten = (blue_density * 1.0 + haze_density.x * 0.25) * (density_multiplier.x * max_y.x);
// Calculate relative weights
temp1 = blue_density + haze_density.x;
blue_weight = blue_density / temp1;
haze_weight = haze_density.x / temp1;
// Compute sunlight from P & lightnorm (for long rays like sky)
temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y );
temp2.y = 1. / temp2.y;
sunlight *= exp( - light_atten * temp2.y);
// Distance
temp2.z = Plen * density_multiplier.x;
// Transparency (-> temp1)
// ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati
// compiler gets confused.
temp1 = exp(-temp1 * temp2.z);
// Compute haze glow
temp2.x = dot(Pn, lightnorm.xyz);
temp2.x = 1. - temp2.x;
// temp2.x is 0 at the sun and increases away from sun
temp2.x = max(temp2.x, .001);
// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
temp2.x *= glow.x;
// Higher glow.x gives dimmer glow (because next step is 1 / "angle")
temp2.x = pow(temp2.x, glow.z);
// glow.z should be negative, so we're doing a sort of (1 / "angle") function
// Add "minimum anti-solar illumination"
temp2.x += .25;
// Increase ambient when there are more clouds
vec4 tmpAmbient = ambient;
tmpAmbient += (1. - tmpAmbient) * cloud_shadow.x * 0.5;
// Dim sunlight by cloud shadow percentage
sunlight *= (1. - cloud_shadow.x);
// Haze color below cloud
vec4 additiveColorBelowCloud = ( blue_horizon * blue_weight * (sunlight + tmpAmbient)
+ (haze_horizon.r * haze_weight) * (sunlight * temp2.x + tmpAmbient)
);
// CLOUDS
sunlight = sunlight_color;
temp2.y = max(0., lightnorm.y * 2.);
temp2.y = 1. / temp2.y;
sunlight *= exp( - light_atten * temp2.y);
// Cloud color out
vary_CloudColorSun = (sunlight * temp2.x) * cloud_color;
vary_CloudColorAmbient = tmpAmbient * cloud_color;
// Attenuate cloud color by atmosphere
temp1 = sqrt(temp1); //less atmos opacity (more transparency) below clouds
vary_CloudColorSun *= temp1;
vary_CloudColorAmbient *= temp1;
vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - temp1);
// Make a nice cloud density based on the cloud_shadow value that was passed in.
vary_CloudDensity = 2. * (cloud_shadow.x - 0.25);
// Texture coords
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[0].xy -= 0.5;
gl_TexCoord[0].xy /= cloud_scale.x;
gl_TexCoord[0].xy += 0.5;
gl_TexCoord[1] = gl_TexCoord[0];
gl_TexCoord[1].x += lightnorm.x * 0.0125;
gl_TexCoord[1].y += lightnorm.z * 0.0125;
gl_TexCoord[2] = gl_TexCoord[0] * 16.;
gl_TexCoord[3] = gl_TexCoord[1] * 16.;
// Combine these to minimize register use
vary_CloudColorAmbient += oHazeColorBelowCloud;
// needs this to compile on mac
//vary_AtmosAttenuation = vec3(0.0,0.0,0.0);
// END CLOUDS
}

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
uniform sampler2D diffuseMap;
@ -20,3 +20,4 @@ void main()
vec3 nvn = normalize(vary_normal);
gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
}

View File

@ -0,0 +1,19 @@
/**
* @file diffuseIndexedF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* $/LicenseInfo$
*/
varying vec3 vary_normal;
void main()
{
vec3 col = gl_Color.rgb * diffuseLookup(gl_TexCoord[0].xy).rgb;
gl_FragData[0] = vec4(col, 0.0);
gl_FragData[1] = gl_Color.aaaa; // spec
//gl_FragData[1] = vec4(vec3(gl_Color.a), gl_Color.a+(1.0-gl_Color.a)*gl_Color.a); // spec - from former class3 - maybe better, but not so well tested
vec3 nvn = normalize(vary_normal);
gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
}

View File

@ -5,7 +5,7 @@
* $License$
*/
#version 120
varying vec3 vary_normal;

View File

@ -5,16 +5,18 @@
* $/LicenseInfo$
*/
#version 120
varying vec3 vary_normal;
varying float vary_texture_index;
void main()
{
//transform vertex
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz, 1.0);
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
vary_texture_index = gl_Vertex.w;
vary_normal = normalize(gl_NormalMatrix * gl_Normal);
gl_FrontColor = gl_Color;

View File

@ -5,60 +5,24 @@
* $/LicenseInfo$
*/
#version 120
#extension GL_ARB_texture_rectangle : enable
uniform sampler2D diffuseMap;
uniform sampler2DRect depthMap;
uniform sampler2D noiseMap;
uniform vec4 shadow_clip;
uniform vec2 screen_res;
vec3 fullbrightAtmosTransport(vec3 light);
vec3 fullbrightScaleSoftClip(vec3 light);
varying vec3 vary_ambient;
varying vec3 vary_directional;
varying vec4 vary_position;
varying vec3 vary_normal;
varying vec3 vary_fragcoord;
uniform mat4 inv_proj;
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).a;
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
void main()
{
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
frag *= screen_res;
vec3 samp_pos = getPosition(frag).xyz;
float shadow = 1.0;
vec4 pos = vary_position;
vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy)*gl_Color;
vec4 color = diffuseLookup(gl_TexCoord[0].xy)*gl_Color;
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
//gl_FragColor = gl_Color;
gl_FragColor = color;
//gl_FragColor = vec4(1,0,1,1);
}

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
void calcAtmospherics(vec3 inPositionEye);
@ -14,30 +14,23 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 scaleDownLight(vec3 light);
vec3 scaleUpLight(vec3 light);
varying vec3 vary_ambient;
varying vec3 vary_directional;
varying vec3 vary_normal;
varying vec3 vary_fragcoord;
uniform float near_clip;
varying vec4 vary_position;
varying float vary_texture_index;
void main()
{
//transform vertex
gl_Position = ftransform();
vec4 vert = vec4(gl_Vertex.xyz, 1.0);
vary_texture_index = gl_Vertex.w;
gl_Position = gl_ModelViewProjectionMatrix*vert;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
vec4 pos = (gl_ModelViewMatrix * gl_Vertex);
vary_position = pos;
vec4 pos = (gl_ModelViewMatrix * vert);
calcAtmospherics(pos.xyz);
gl_FrontColor = gl_Color;
gl_FogFragCoord = pos.z;
pos = gl_ModelViewProjectionMatrix * gl_Vertex;
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
}

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
#extension GL_ARB_texture_rectangle : enable

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
varying vec2 vary_fragcoord;

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
uniform sampler2D diffuseMap;
uniform sampler2D normalMap;

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
void main()
{

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
uniform sampler2DRect diffuseMap;

View File

@ -5,7 +5,7 @@
* $/LicenseInfo$
*/
#version 120
varying vec2 vary_fragcoord;

Some files were not shown because too many files have changed in this diff Show More