merging up from viewer-development

master
Aaron Terrell (Enus) 2010-08-30 11:56:33 -07:00
commit d04e8d7575
569 changed files with 12486 additions and 9888 deletions

View File

@ -3,6 +3,7 @@
0962101bfa7df0643a6e625786025fe7f8a6dc97 2-1-beta-2
12769e547e30067d494a6c01479a18107366ce2f beta-5
17fc2908e9a1ef34a9f53a41a393caf5c3cac390 beta-3-5
19547b909b404552593be5ec7c18241e062a6d65 2-1-1-beta-1
1e2b517adc2ecb342cd3c865f2a6ccf82a3cf8d7 2-1-beta-3
3469d90a115b900f8f250e137bbd9b684130f5d2 beta-4
3e4b947f79d88c385e8218cbc0731cef0e42cfc4 2-1-beta-1
@ -10,11 +11,13 @@
4f777ffb99fefdc6497c61385c22688ff149c659 viewer-2-0-0
52d96ad3d39be29147c5b2181b3bb46af6164f0e alpha-3
668851b2ef0f8cf8df07a0fba429e4a6c1e70abb viewer-2-0-1
6e3b2e13906ba8ff22d3c8490b02d518adb2c907 2-1-1-beta-2
7f16e79826d377f5f9f5b33dc721ab56d0d7dc8f alpha-4
7f16e79826d377f5f9f5b33dc721ab56d0d7dc8f fork to viewer-20qa
80bc6cff515118a36108967af49d3f8105c95bc9 viewer-2-0-2-start
b03065d018b8a2e28b7de85b293a4c992cb4c12d 2-1-release
b8419565906e4feb434426d8d9b17dd1458e24b2 alpha-6
bb38ff1a763738609e1b3cada6d15fa61e5e84b9 2-1-1-release
c6969fe44e58c542bfc6f1bd6c0be2fa860929ac 2-1-beta-4
d2382d374139850efa5bb6adfb229e3e656cfc40 howard-demo
d40ac9dd949cba6dab1cc386da6a2027690c2519 alpha-5

View File

@ -1,19 +1,15 @@
# BuildParams
#
# Please refer to:
# https://wiki.lindenlab.com/wiki/Parabuild_with_Mercurial#How_Build_Parameters_Work
# https://wiki.secondlife.com/wiki/Automated_Build_System
# Global setting for now...
Darwin.symbolfiles = "newview/Release/secondlife-symbols-darwin.tar.bz2"
CYGWIN.symbolfiles = "newview/Release/secondlife-symbols-windows.tar.bz2"
Linux.symbolfiles = "newview/secondlife-symbols-linux.tar.bz2"
# Public Upload Locations overriding the default private ones
S3PROXY_URL = http://automated-builds-secondlife-com.s3.amazonaws.com/
S3INTERNAL_URL = http://automated-builds-secondlife-com.s3.amazonaws.com/
S3GET_URL = http://automated-builds-secondlife-com.s3.amazonaws.com/
S3PUT_URL = https://s3.amazonaws.com/automated-builds-secondlife-com/
S3ACL = public-read
# Use Public Upload Locations
public_build = true
# Update Public Inworld Build Status Indicators
email_status_this_is_os = true
@ -27,26 +23,7 @@ viewer-development.show_changes_since = 2-1-release
# Build Settings
viewer-development_coverity.coverity_product = viewer
viewer-development.build_Linux = true
viewer-development_debug.build_Linux = false
viewer-development_coverity.build_Linux = false
viewer-development.build_Darwin = true
viewer-development_debug.build_Darwin = false
viewer-development_coverity.build_Darwin = false
viewer-development.build_CYGWIN = true
viewer-development.build_CYGWIN_Debug = false
viewer-development.build_CYGWIN_RelWithDebInfo = false
viewer-development.build_CYGWIN_Release = true
viewer-development_debug.build_CYGWIN_Debug = true
viewer-development_debug.build_CYGWIN_RelWithDebInfo = true
viewer-development_debug.build_CYGWIN_Release = false
viewer-development_coverity.build_coverity = true
viewer-development_coverity.build_CYGWIN_Debug = false
viewer-development_coverity.build_CYGWIN_RelWithDebInfo = false
viewer-development_coverity.build_CYGWIN_Release = true
viewer-development.build_debug_release_separately = true
# Notifications - to configure email notices, add a setting like this:
# <username>_<reponame>.email = <email-address>
@ -173,6 +150,28 @@ oz_viewer-review1_coverity.build_CYGWIN_Debug = false
oz_viewer-review1_coverity.build_CYGWIN_RelWithDebInfo = false
oz_viewer-review1_coverity.build_CYGWIN_Release = false
oz_viewer-review2_coverity.coverity_product = viewer
oz_viewer-review2.build_Linux = true
oz_viewer-review2_debug.build_Linux = false
oz_viewer-review2_coverity.build_Linux = false
oz_viewer-review2.build_Darwin = true
oz_viewer-review2_debug.build_Darwin = false
oz_viewer-review2_coverity.build_Darwin = false
oz_viewer-review2.build_CYGWIN = true
oz_viewer-review2.build_CYGWIN_Debug = false
oz_viewer-review2.build_CYGWIN_RelWithDebInfo = false
oz_viewer-review2.build_CYGWIN_Release = true
oz_viewer-review2_debug.build_CYGWIN_Debug = true
oz_viewer-review2_debug.build_CYGWIN_RelWithDebInfo = true
oz_viewer-review2_debug.build_CYGWIN_Release = false
oz_viewer-review2_coverity.build_coverity = true
oz_viewer-review2_coverity.build_CYGWIN_Debug = false
oz_viewer-review2_coverity.build_CYGWIN_RelWithDebInfo = false
oz_viewer-review2_coverity.build_CYGWIN_Release = false
# ========================================
# enus
# ========================================

View File

@ -64,6 +64,7 @@ Aleric Inglewood
VWR-12691
VWR-13996
VWR-14426
SNOW-766
Ales Beaumont
VWR-9352
Alissa Sabre
@ -127,6 +128,8 @@ Asuka Neely
VWR-8179
Balp Allen
VWR-4157
Be Holder
SNOW-397
Benja Kepler
VWR-746
Biancaluce Robbiani
@ -153,6 +156,7 @@ Boroondas Gupte
SNOW-503
SNOW-510
SNOW-527
SNOW-610
SNOW-624
VWR-233
WEB-262
@ -212,6 +216,8 @@ Dzonatas Sol
VWR-1705
VWR-1729
VWR-1812
Eddi Decosta
SNOW-586
Eddy Stryker
VWR-15
VWR-23
@ -632,6 +638,7 @@ Tharax Ferraris
VWR-605
Thickbrick Sleaford
SNOW-207
SNOW-586
SNOW-743
VWR-7109
VWR-9287

View File

@ -3,18 +3,5 @@ include(Prebuilt)
if (INSTALL_PROPRIETARY AND NOT STANDALONE)
use_prebuilt_binary(kdu)
if (EXISTS ${LIBS_CLOSED_DIR}/llkdu)
if (WINDOWS)
set(KDU_LIBRARY debug kdu_cored optimized kdu_core)
else (WINDOWS)
set(KDU_LIBRARY kdu)
endif (WINDOWS)
set(KDU_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
set(LLKDU_LIBRARY llkdu)
set(LLKDU_STATIC_LIBRARY llkdu_static)
set(LLKDU_LIBRARIES ${LLKDU_LIBRARY})
set(LLKDU_STATIC_LIBRARIES ${LLKDU_STATIC_LIBRARY})
endif (EXISTS ${LIBS_CLOSED_DIR}/llkdu)
set(LLKDU_LIBRARY llkdu)
endif (INSTALL_PROPRIETARY AND NOT STANDALONE)

View File

@ -7,3 +7,10 @@ if (NOT STANDALONE)
use_prebuilt_binary(fontconfig)
endif(NOT STANDALONE)
if(VIEWER AND NOT STANDALONE)
if(EXISTS ${CMAKE_SOURCE_DIR}/newview/res/have_artwork_bundle.marker)
message(STATUS "We seem to have an artwork bundle in the tree - brilliant.")
else(EXISTS ${CMAKE_SOURCE_DIR}/newview/res/have_artwork_bundle.marker)
message(FATAL_ERROR "Didn't find an artwork bundle - this needs to be downloaded separately and unpacked into this tree. You can probably get it from the same place you got your viewer source. Thanks!")
endif(EXISTS ${CMAKE_SOURCE_DIR}/newview/res/have_artwork_bundle.marker)
endif(VIEWER AND NOT STANDALONE)

View File

@ -742,9 +742,10 @@ Options:
-p | --project=NAME set the root project name. (Doesn't effect makefiles)
Commands:
build configure and build default target
clean delete all build directories, does not affect sources
configure configure project by running cmake (default command if none given)
build configure and build default target
clean delete all build directories, does not affect sources
configure configure project by running cmake (default if none given)
printbuilddirs print the build directory that will be used
Command-options for "configure":
We use cmake variables to change the build configuration.
@ -762,15 +763,6 @@ Examples:
'''
def main(arguments):
if os.getenv('DISTCC_DIR') is None:
distcc_dir = os.path.join(getcwd(), '.distcc')
if not os.path.exists(distcc_dir):
os.mkdir(distcc_dir)
print "setting DISTCC_DIR to %s" % distcc_dir
os.environ['DISTCC_DIR'] = distcc_dir
else:
print "DISTCC_DIR is set to %s" % os.getenv('DISTCC_DIR')
setup = setup_platform[sys.platform]()
try:
opts, args = getopt.getopt(
@ -832,6 +824,14 @@ For example: develop.py configure -DSERVER:BOOL=OFF"""
if cmd in ('cmake', 'configure'):
setup.run_cmake(args)
elif cmd == 'build':
if os.getenv('DISTCC_DIR') is None:
distcc_dir = os.path.join(getcwd(), '.distcc')
if not os.path.exists(distcc_dir):
os.mkdir(distcc_dir)
print "setting DISTCC_DIR to %s" % distcc_dir
os.environ['DISTCC_DIR'] = distcc_dir
else:
print "DISTCC_DIR is set to %s" % os.getenv('DISTCC_DIR')
for d in setup.build_dirs():
if not os.path.exists(d):
raise CommandError('run "develop.py cmake" first')
@ -842,6 +842,9 @@ For example: develop.py configure -DSERVER:BOOL=OFF"""
if args:
raise CommandError('clean takes no arguments')
setup.cleanup()
elif cmd == 'printbuilddirs':
for d in setup.build_dirs():
print >> sys.stdout, d
else:
print >> sys.stderr, 'Error: unknown subcommand', repr(cmd)
print >> sys.stderr, "(run 'develop.py --help' for help)"

View File

@ -196,7 +196,7 @@ public:
{
U32 n = mVector.size();
mIndexMap[k] = n;
mVector.resize(n+1);
mVector.push_back(Type());
llassert(mVector.size() == mIndexMap.size());
return mVector[n];
}

View File

@ -45,7 +45,7 @@ public:
void setStride (S32 skipBytes) { mSkip = (skipBytes ? skipBytes : sizeof(Object));}
void skip(const U32 index) { mBytep += mSkip*index;}
U32 getSkip() const { return mSkip; }
Object* get() { return mObjectp; }
Object* operator->() { return mObjectp; }
Object& operator *() { return *mObjectp; }

View File

@ -30,7 +30,7 @@
const S32 LL_VERSION_MAJOR = 2;
const S32 LL_VERSION_MINOR = 1;
const S32 LL_VERSION_PATCH = 0;
const S32 LL_VERSION_BUILD = 0;
const S32 LL_VERSION_BUILD = 13828;
const char * const LL_CHANNEL = "Second Life Server";

View File

@ -369,6 +369,8 @@ void LLCrashLogger::updateApplication(const std::string& message)
bool LLCrashLogger::init()
{
LLCurl::initClass();
// We assume that all the logs we're looking for reside on the current drive
gDirUtilp->initAppDirs("SecondLife");

View File

@ -52,7 +52,6 @@ static const std::string PARCEL_OWNERSHIP_STATUS_STRING[LLParcel::OS_COUNT+1] =
};
// NOTE: Adding parcel categories also requires updating:
// * floater_directory.xml category combobox
// * floater_about_land.xml category combobox
// * Web site "create event" tools
// DO NOT DELETE ITEMS FROM THIS LIST WITHOUT DEEPLY UNDERSTANDING WHAT YOU'RE DOING.

View File

@ -80,6 +80,8 @@ const F32 SKEW_MAX = 0.95f;
const F32 SCULPT_MIN_AREA = 0.002f;
const S32 SCULPT_MIN_AREA_DETAIL = 1;
#define GEN_TRI_STRIP 0
BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm)
{
LLVector3 test = (pt2-pt1)%(pt3-pt2);
@ -1682,7 +1684,7 @@ LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL ge
mGenerateSingleFace = generate_single_face;
generate();
if (mParams.getSculptID().isNull())
if (mParams.getSculptID().isNull() && params.getSculptType() == LL_SCULPT_TYPE_NONE)
{
createVolumeFaces();
}
@ -1858,6 +1860,11 @@ void LLVolume::createVolumeFaces()
LLProfile::Face& face = mProfilep->mFaces[i];
vf.mBeginS = face.mIndex;
vf.mNumS = face.mCount;
if (vf.mNumS < 0)
{
llerrs << "Volume face corruption detected." << llendl;
}
vf.mBeginT = 0;
vf.mNumT= getPath().mPath.size();
vf.mID = i;
@ -1901,6 +1908,10 @@ void LLVolume::createVolumeFaces()
if (face.mFlat && vf.mNumS > 2)
{ //flat inner faces have to copy vert normals
vf.mNumS = vf.mNumS*2;
if (vf.mNumS < 0)
{
llerrs << "Volume face corruption detected." << llendl;
}
}
}
else
@ -4515,7 +4526,9 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
if (!partial_build)
{
#if GEN_TRI_STRIP
mTriStrip.clear();
#endif
S32 idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0};
for(S32 gx = 0;gx<grid_size;gx++)
{
@ -4529,6 +4542,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]);
}
#if GEN_TRI_STRIP
if (gy == 0)
{
mTriStrip.push_back((gx+1)*(grid_size+1));
@ -4544,6 +4558,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
{
mTriStrip.push_back(gy+1+gx*(grid_size+1));
}
#endif
}
else
{
@ -4552,6 +4567,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]);
}
#if GEN_TRI_STRIP
if (gy == 0)
{
mTriStrip.push_back(gx*(grid_size+1));
@ -4566,15 +4582,18 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
{
mTriStrip.push_back(gy+1+(gx+1)*(grid_size+1));
}
#endif
}
}
}
#if GEN_TRI_STRIP
if (mTriStrip.size()%2 == 1)
{
mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]);
}
#endif
}
return TRUE;
@ -4944,6 +4963,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
mIndices[3*i+v2] = i + 1;
}
#if GEN_TRI_STRIP
//make tri strip
if (mTypeMask & OPEN_MASK)
{
@ -4986,6 +5006,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]);
}
}
#endif
}
return TRUE;
@ -4993,6 +5014,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
void LLVolumeFace::makeTriStrip()
{
#if GEN_TRI_STRIP
for (U32 i = 0; i < mIndices.size(); i+=3)
{
U16 i0 = mIndices[i];
@ -5021,6 +5043,7 @@ void LLVolumeFace::makeTriStrip()
{
mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]);
}
#endif
}
void LLVolumeFace::createBinormals()
@ -5106,12 +5129,6 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
mHasBinormals = FALSE;
}
LLVector3& face_min = mExtents[0];
LLVector3& face_max = mExtents[1];
mCenter.clearVec();
S32 begin_stex = llfloor( profile[mBeginS].mV[2] );
S32 num_s = ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2) ? mNumS/2 : mNumS;
@ -5167,15 +5184,6 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
mVertices[cur_vertex].mNormal = LLVector3(0,0,0);
mVertices[cur_vertex].mBinormal = LLVector3(0,0,0);
if (cur_vertex == 0)
{
face_min = face_max = mesh[i].mPos;
}
else
{
update_min_max(face_min, face_max, mesh[i].mPos);
}
cur_vertex++;
@ -5209,12 +5217,22 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
mVertices[cur_vertex].mNormal = LLVector3(0,0,0);
mVertices[cur_vertex].mBinormal = LLVector3(0,0,0);
update_min_max(face_min,face_max,mesh[i].mPos);
cur_vertex++;
}
}
//get bounding box for this side
LLVector3& face_min = mExtents[0];
LLVector3& face_max = mExtents[1];
mCenter.clearVec();
face_min = face_max = mVertices[0].mPosition;
for (U32 i = 1; i < mVertices.size(); ++i)
{
update_min_max(face_min, face_max, mVertices[i].mPosition);
}
mCenter = (face_min + face_max) * 0.5f;
S32 cur_index = 0;
@ -5223,13 +5241,17 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
if (!partial_build)
{
#if GEN_TRI_STRIP
mTriStrip.clear();
#endif
// Now we generate the indices.
for (t = 0; t < (mNumT-1); t++)
{
#if GEN_TRI_STRIP
//prepend terminating index to strip
mTriStrip.push_back(mNumS*t);
#endif
for (s = 0; s < (mNumS-1); s++)
{
@ -5240,6 +5262,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
mIndices[cur_index++] = s+1 + mNumS*t; //bottom right
mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right
#if GEN_TRI_STRIP
if (s == 0)
{
mTriStrip.push_back(s+mNumS*t);
@ -5247,6 +5270,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
}
mTriStrip.push_back(s+1+mNumS*t);
mTriStrip.push_back(s+1+mNumS*(t+1));
#endif
mEdge[cur_edge++] = (mNumS-1)*2*t+s*2+1; //bottom left/top right neighbor face
if (t < mNumT-2) { //top right/top left neighbor face
@ -5288,44 +5312,37 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
}
mEdge[cur_edge++] = (mNumS-1)*2*t+s*2; //top right/bottom left neighbor face
}
#if GEN_TRI_STRIP
//append terminating vertex to strip
mTriStrip.push_back(mNumS-1+mNumS*(t+1));
#endif
}
#if GEN_TRI_STRIP
if (mTriStrip.size()%2 == 1)
{
mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]);
}
#endif
}
//generate normals
for (U32 i = 0; i < mIndices.size()/3; i++) //for each triangle
{
const S32 i0 = mIndices[i*3+0];
const S32 i1 = mIndices[i*3+1];
const S32 i2 = mIndices[i*3+2];
const VertexData& v0 = mVertices[i0];
const VertexData& v1 = mVertices[i1];
const VertexData& v2 = mVertices[i2];
const U16* idx = &(mIndices[i*3]);
VertexData* v[] =
{ &mVertices[idx[0]], &mVertices[idx[1]], &mVertices[idx[2]] };
//calculate triangle normal
LLVector3 norm = (v0.mPosition-v1.mPosition) % (v0.mPosition-v2.mPosition);
LLVector3 norm = (v[0]->mPosition-v[1]->mPosition) % (v[0]->mPosition-v[2]->mPosition);
for (U32 j = 0; j < 3; j++)
{ //add triangle normal to vertices
const S32 idx = mIndices[i*3+j];
mVertices[idx].mNormal += norm; // * (weight_sum - d[j])/weight_sum;
}
v[0]->mNormal += norm;
v[1]->mNormal += norm;
v[2]->mNormal += norm;
//even out quad contributions
if ((i & 1) == 0)
{
mVertices[i2].mNormal += norm;
}
else
{
mVertices[i1].mNormal += norm;
}
v[i%2+1]->mNormal += norm;
}
// adjust normals based on wrapping and stitching

View File

@ -234,9 +234,14 @@ static void request(
lldebugs << LLURLRequest::actionAsVerb(method) << " " << url << " "
<< headers << llendl;
// Insert custom headers is the caller sent any
if (headers.isMap())
{
// Insert custom headers if the caller sent any
if (headers.isMap())
{
if (headers.has("Cookie"))
{
req->allowCookies();
}
LLSD::map_const_iterator iter = headers.beginMap();
LLSD::map_const_iterator end = headers.endMap();

View File

@ -438,13 +438,13 @@ void LLPumpIO::pump()
pump(DEFAULT_POLL_TIMEOUT);
}
static LLFastTimer::DeclareTimer FTM_PUMP("Pump");
static LLFastTimer::DeclareTimer FTM_PUMP_IO("Pump IO");
//timeout is in microseconds
void LLPumpIO::pump(const S32& poll_timeout)
{
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
LLFastTimer t1(FTM_PUMP);
LLFastTimer t1(FTM_PUMP_IO);
//llinfos << "LLPumpIO::pump()" << llendl;
// Run any pending runners.
@ -772,6 +772,8 @@ bool LLPumpIO::respond(
return true;
}
static LLFastTimer::DeclareTimer FTM_PUMP_CALLBACK_CHAIN("Chain");
void LLPumpIO::callback()
{
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
@ -793,6 +795,7 @@ void LLPumpIO::callback()
callbacks_t::iterator end = mCallbacks.end();
for(; it != end; ++it)
{
LLFastTimer t(FTM_PUMP_CALLBACK_CHAIN);
// it's always the first and last time for respone chains
(*it).mHead = (*it).mChainLinks.begin();
(*it).mInit = true;

View File

@ -245,6 +245,11 @@ void LLURLRequest::useProxy(const std::string &proxy)
mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, proxy);
}
void LLURLRequest::allowCookies()
{
mDetail->mCurlRequest->setoptString(CURLOPT_COOKIEFILE, "");
}
// virtual
LLIOPipe::EStatus LLURLRequest::handleError(
LLIOPipe::EStatus status,

View File

@ -183,6 +183,11 @@ public:
*/
void useProxy(const std::string& proxy);
/**
* @brief Turn on cookie handling for this request with CURLOPT_COOKIEFILE.
*/
void allowCookies();
public:
/**
* @brief Give this pipe a chance to handle a generated error

View File

@ -280,6 +280,7 @@ public:
void setLightTexture(const LLUUID& id) { mLightTexture = id; }
LLUUID getLightTexture() const { return mLightTexture; }
bool isLightSpotlight() const { return mLightTexture.notNull(); }
void setParams(const LLVector3& params) { mParams = params; }
LLVector3 getParams() const { return mParams; }

View File

@ -253,10 +253,10 @@ F32 LLFontFreetype::getXAdvance(llwchar wch) const
}
else
{
gi = get_if_there(mCharGlyphInfoMap, (llwchar)0, (LLFontGlyphInfo*)NULL);
if (gi)
char_glyph_info_map_t::iterator found_it = mCharGlyphInfoMap.find((llwchar)0);
if (found_it != mCharGlyphInfoMap.end())
{
return gi->mXAdvance;
return found_it->second->mXAdvance;
}
}

View File

@ -27,7 +27,7 @@
#ifndef LL_LLFONTFREETYPE_H
#define LL_LLFONTFREETYPE_H
#include <map>
#include <boost/unordered_map.hpp>
#include "llpointer.h"
#include "llstl.h"
@ -164,7 +164,7 @@ private:
BOOL mValid;
typedef std::map<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;
typedef boost::unordered_map<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;
mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap
mutable LLPointer<LLFontBitmapCache> mFontBitmapCachep;

View File

@ -141,6 +141,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect
S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses) const
{
LLFastTimer _(FTM_RENDER_FONTS);
if(!sDisplayFont) //do not display texts
{
return wstr.length() ;
@ -175,16 +177,18 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
gGL.loadUIIdentity();
gGL.translateUI(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY), sCurOrigin.mZ);
//gGL.translateUI(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY), sCurOrigin.mZ);
// this code snaps the text origin to a pixel grid to start with
F32 pixel_offset_x = llround((F32)sCurOrigin.mX) - (sCurOrigin.mX);
F32 pixel_offset_y = llround((F32)sCurOrigin.mY) - (sCurOrigin.mY);
gGL.translateUI(-pixel_offset_x, -pixel_offset_y, 0.f);
//F32 pixel_offset_x = llround((F32)sCurOrigin.mX) - (sCurOrigin.mX);
//F32 pixel_offset_y = llround((F32)sCurOrigin.mY) - (sCurOrigin.mY);
//gGL.translateUI(-pixel_offset_x, -pixel_offset_y, 0.f);
LLFastTimer t(FTM_RENDER_FONTS);
LLVector2 origin(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY));
// snap the text origin to a pixel grid to start with
origin.mV[VX] -= llround((F32)sCurOrigin.mX) - (sCurOrigin.mX);
origin.mV[VY] -= llround((F32)sCurOrigin.mY) - (sCurOrigin.mY);
gGL.color4fv( color.mV );
S32 chars_drawn = 0;
S32 i;
@ -204,8 +208,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
// Not guaranteed to be set correctly
gGL.setSceneBlendType(LLRender::BT_ALPHA);
cur_x = ((F32)x * sScaleX);
cur_y = ((F32)y * sScaleY);
cur_x = ((F32)x * sScaleX) + origin.mV[VX];
cur_y = ((F32)y * sScaleY) + origin.mV[VY];
// Offset y by vertical alignment.
switch (valign)
@ -270,6 +274,15 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
const LLFontGlyphInfo* next_glyph = NULL;
const S32 GLYPH_BATCH_SIZE = 30;
LLVector3 vertices[GLYPH_BATCH_SIZE * 4];
LLVector2 uvs[GLYPH_BATCH_SIZE * 4];
LLColor4U colors[GLYPH_BATCH_SIZE * 4];
LLColor4U text_color(color);
S32 bitmap_num = -1;
S32 glyph_count = 0;
for (i = begin_offset; i < begin_offset + length; i++)
{
llwchar wch = wstr[i];
@ -286,8 +299,13 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
break;
}
// Per-glyph bitmap texture.
LLImageGL *image_gl = mFontFreetype->getFontBitmapCache()->getImageGL(fgi->mBitmapNum);
gGL.getTexUnit(0)->bind(image_gl);
S32 next_bitmap_num = fgi->mBitmapNum;
if (next_bitmap_num != bitmap_num)
{
bitmap_num = next_bitmap_num;
LLImageGL *font_image = font_bitmap_cache->getImageGL(bitmap_num);
gGL.getTexUnit(0)->bind(font_image);
}
if ((start_x + scaled_max_pixels) < (cur_x + fgi->mXBearing + fgi->mWidth))
{
@ -307,7 +325,18 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,
llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight);
drawGlyph(screen_rect, uv_rect, color, style_to_add, shadow, drop_shadow_strength);
if (glyph_count >= GLYPH_BATCH_SIZE)
{
gGL.begin(LLRender::QUADS);
{
gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4);
}
gGL.end();
glyph_count = 0;
}
drawGlyph(glyph_count, vertices, uvs, colors, screen_rect, uv_rect, text_color, style_to_add, shadow, drop_shadow_strength);
chars_drawn++;
cur_x += fgi->mXAdvance;
@ -332,11 +361,19 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
cur_render_y = cur_y;
}
gGL.begin(LLRender::QUADS);
{
gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4);
}
gGL.end();
if (right_x)
{
*right_x = cur_x / sScaleX;
*right_x = (cur_x - origin.mV[VX]) / sScaleX;
}
//FIXME: add underline as glyph?
if (style_to_add & UNDERLINE)
{
F32 descender = mFontFreetype->getDescenderHeight();
@ -356,7 +393,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
gGL.pushUIMatrix();
renderUTF8(std::string("..."),
0,
cur_x / sScaleX, (F32)y,
(cur_x - origin.mV[VX]) / sScaleX, (F32)y,
color,
LEFT, valign,
style_to_add,
@ -1085,95 +1122,95 @@ LLFontGL &LLFontGL::operator=(const LLFontGL &source)
return *this;
}
void LLFontGL::renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const
void LLFontGL::renderQuad(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const
{
gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
gGL.vertex2f(llfont_round_x(screen_rect.mRight),
llfont_round_y(screen_rect.mTop));
S32 index = 0;
gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
gGL.vertex2f(llfont_round_x(screen_rect.mLeft),
llfont_round_y(screen_rect.mTop));
vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mRight), llfont_round_y(screen_rect.mTop), 0.f);
uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
colors_out[index] = color;
index++;
gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
gGL.vertex2f(llfont_round_x(screen_rect.mLeft + slant_amt),
llfont_round_y(screen_rect.mBottom));
vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mLeft), llfont_round_y(screen_rect.mTop), 0.f);
uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
colors_out[index] = color;
index++;
gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
gGL.vertex2f(llfont_round_x(screen_rect.mRight + slant_amt),
llfont_round_y(screen_rect.mBottom));
vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mLeft), llfont_round_y(screen_rect.mBottom), 0.f);
uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
colors_out[index] = color;
index++;
vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mRight), llfont_round_y(screen_rect.mBottom), 0.f);
uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
colors_out[index] = color;
}
void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const
void LLFontGL::drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const
{
F32 slant_offset;
slant_offset = ((style & ITALIC) ? ( -mFontFreetype->getAscenderHeight() * 0.2f) : 0.f);
gGL.begin(LLRender::QUADS);
//FIXME: bold and drop shadow are mutually exclusive only for convenience
//Allow both when we need them.
if (style & BOLD)
{
//FIXME: bold and drop shadow are mutually exclusive only for convenience
//Allow both when we need them.
if (style & BOLD)
for (S32 pass = 0; pass < 2; pass++)
{
gGL.color4fv(color.mV);
for (S32 pass = 0; pass < 2; pass++)
{
LLRectf screen_rect_offset = screen_rect;
LLRectf screen_rect_offset = screen_rect;
screen_rect_offset.translate((F32)(pass * BOLD_OFFSET), 0.f);
renderQuad(screen_rect_offset, uv_rect, slant_offset);
}
screen_rect_offset.translate((F32)(pass * BOLD_OFFSET), 0.f);
renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_offset, uv_rect, color, slant_offset);
glyph_count++;
}
else if (shadow == DROP_SHADOW_SOFT)
{
LLColor4 shadow_color = LLFontGL::sShadowColor;
shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength * DROP_SHADOW_SOFT_STRENGTH;
gGL.color4fv(shadow_color.mV);
for (S32 pass = 0; pass < 5; pass++)
{
LLRectf screen_rect_offset = screen_rect;
switch(pass)
{
case 0:
screen_rect_offset.translate(-1.f, -1.f);
break;
case 1:
screen_rect_offset.translate(1.f, -1.f);
break;
case 2:
screen_rect_offset.translate(1.f, 1.f);
break;
case 3:
screen_rect_offset.translate(-1.f, 1.f);
break;
case 4:
screen_rect_offset.translate(0, -2.f);
break;
}
renderQuad(screen_rect_offset, uv_rect, slant_offset);
}
gGL.color4fv(color.mV);
renderQuad(screen_rect, uv_rect, slant_offset);
}
else if (shadow == DROP_SHADOW)
{
LLColor4 shadow_color = LLFontGL::sShadowColor;
shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength;
gGL.color4fv(shadow_color.mV);
LLRectf screen_rect_shadow = screen_rect;
screen_rect_shadow.translate(1.f, -1.f);
renderQuad(screen_rect_shadow, uv_rect, slant_offset);
gGL.color4fv(color.mV);
renderQuad(screen_rect, uv_rect, slant_offset);
}
else // normal rendering
{
gGL.color4fv(color.mV);
renderQuad(screen_rect, uv_rect, slant_offset);
}
}
gGL.end();
else if (shadow == DROP_SHADOW_SOFT)
{
LLColor4U shadow_color = LLFontGL::sShadowColor;
shadow_color.mV[VALPHA] = U8(color.mV[VALPHA] * drop_shadow_strength * DROP_SHADOW_SOFT_STRENGTH);
for (S32 pass = 0; pass < 5; pass++)
{
LLRectf screen_rect_offset = screen_rect;
switch(pass)
{
case 0:
screen_rect_offset.translate(-1.f, -1.f);
break;
case 1:
screen_rect_offset.translate(1.f, -1.f);
break;
case 2:
screen_rect_offset.translate(1.f, 1.f);
break;
case 3:
screen_rect_offset.translate(-1.f, 1.f);
break;
case 4:
screen_rect_offset.translate(0, -2.f);
break;
}
renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_offset, uv_rect, shadow_color, slant_offset);
glyph_count++;
}
renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset);
glyph_count++;
}
else if (shadow == DROP_SHADOW)
{
LLColor4U shadow_color = LLFontGL::sShadowColor;
shadow_color.mV[VALPHA] = U8(color.mV[VALPHA] * drop_shadow_strength);
LLRectf screen_rect_shadow = screen_rect;
screen_rect_shadow.translate(1.f, -1.f);
renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_shadow, uv_rect, shadow_color, slant_offset);
glyph_count++;
renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset);
glyph_count++;
}
else // normal rendering
{
renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset);
glyph_count++;
}
}

View File

@ -211,8 +211,8 @@ private:
LLFontDescriptor mFontDescriptor;
LLPointer<LLFontFreetype> mFontFreetype;
void renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const;
void drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const;
void renderQuad(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const;
void drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const;
// Registry holds all instantiated fonts.
static LLFontRegistry* sFontRegistry;

View File

@ -179,6 +179,9 @@ PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT =
// GL_EXT_framebuffer_blit
PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT = NULL;
// GL_EXT_blend_func_separate
PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT = NULL;
// GL_ARB_draw_buffers
PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB = NULL;
@ -318,6 +321,7 @@ LLGLManager::LLGLManager() :
mHasCompressedTextures(FALSE),
mHasFramebufferObject(FALSE),
mHasFramebufferMultisample(FALSE),
mHasBlendFuncSeparate(FALSE),
mHasVertexBufferObject(FALSE),
mHasPBuffer(FALSE),
@ -346,6 +350,8 @@ LLGLManager::LLGLManager() :
mHasSeparateSpecularColor(FALSE),
mDebugGPU(FALSE),
mDriverVersionMajor(1),
mDriverVersionMinor(0),
mDriverVersionRelease(0),
@ -513,11 +519,23 @@ bool LLGLManager::initGL()
return false;
}
setToDebugGPU();
initGLStates();
return true;
}
void LLGLManager::setToDebugGPU()
{
//"MOBILE INTEL(R) 965 EXPRESS CHIP",
if (mGLRenderer.find("INTEL") != std::string::npos && mGLRenderer.find("965") != std::string::npos)
{
mDebugGPU = TRUE ;
}
return ;
}
void LLGLManager::getGLInfo(LLSD& info)
{
info["GLInfo"]["GLVendor"] = std::string((const char *)glGetString(GL_VENDOR));
@ -626,6 +644,11 @@ void LLGLManager::initExtensions()
mHasDrawBuffers = TRUE;
#else
mHasDrawBuffers = FALSE;
# endif
# if GL_EXT_blend_func_separate
mHasBlendFuncSeparate = TRUE;
#else
mHasBlendFuncSeparate = FALSE;
# endif
mHasMipMapGeneration = FALSE;
mHasSeparateSpecularColor = FALSE;
@ -653,6 +676,7 @@ void LLGLManager::initExtensions()
&& ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
mHasFramebufferMultisample = mHasFramebufferObject && ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts);
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);
#if !LL_DARWIN
mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
@ -676,6 +700,7 @@ void LLGLManager::initExtensions()
mHasFramebufferObject = FALSE;
mHasFramebufferMultisample = FALSE;
mHasDrawBuffers = FALSE;
mHasBlendFuncSeparate = FALSE;
mHasMipMapGeneration = FALSE;
mHasSeparateSpecularColor = FALSE;
mHasAnisotropic = FALSE;
@ -700,6 +725,7 @@ void LLGLManager::initExtensions()
mHasShaderObjects = FALSE;
mHasVertexShader = FALSE;
mHasFragmentShader = FALSE;
mHasBlendFuncSeparate = FALSE;
LL_WARNS("RenderInit") << "GL extension support forced to SIMPLE level via LL_GL_BASICEXT" << LL_ENDL;
}
if (getenv("LL_GL_BLACKLIST")) /* Flawfinder: ignore */
@ -728,7 +754,8 @@ void LLGLManager::initExtensions()
if (strchr(blacklist,'r')) mHasDrawBuffers = FALSE;//S
if (strchr(blacklist,'s')) mHasFramebufferMultisample = FALSE;
if (strchr(blacklist,'t')) mHasTextureRectangle = FALSE;
if (strchr(blacklist,'u')) mHasBlendFuncSeparate = FALSE;//S
}
#endif // LL_LINUX || LL_SOLARIS
@ -776,6 +803,14 @@ void LLGLManager::initExtensions()
{
LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_fragment_shader" << LL_ENDL;
}
if (!mHasBlendFuncSeparate)
{
LL_INFOS("RenderInit") << "Couldn't initialize GL_EXT_blend_func_separate" << LL_ENDL;
}
if (!mHasDrawBuffers)
{
LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_draw_buffers" << LL_ENDL;
}
// Disable certain things due to known bugs
if (mIsIntel && mHasMipMapGeneration)
@ -846,6 +881,10 @@ void LLGLManager::initExtensions()
{
glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDrawBuffersARB");
}
if (mHasBlendFuncSeparate)
{
glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBlendFuncSeparateEXT");
}
#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");
@ -1008,24 +1047,9 @@ void flush_glerror()
glGetError();
}
void assert_glerror()
void do_assert_glerror()
{
if (!gGLActive)
{
//llwarns << "GL used while not active!" << llendl;
if (gDebugSession)
{
//ll_fail("GL used while not active");
}
}
if (gNoRender || !gDebugGL)
{
return;
}
if (!gGLManager.mInited)
if (LL_UNLIKELY(!gGLManager.mInited))
{
LL_ERRS("RenderInit") << "GL not initialized" << LL_ENDL;
}
@ -1033,10 +1057,9 @@ void assert_glerror()
GLenum error;
error = glGetError();
BOOL quit = FALSE;
while (error)
while (LL_UNLIKELY(error))
{
quit = TRUE;
#ifndef LL_LINUX // *FIX: ! This should be an error for linux as well.
GLubyte const * gl_error_msg = gluErrorString(error);
if (NULL != gl_error_msg)
{
@ -1060,7 +1083,6 @@ void assert_glerror()
}
}
error = glGetError();
#endif
}
if (quit)
@ -1076,6 +1098,25 @@ void assert_glerror()
}
}
void assert_glerror()
{
if (!gGLActive)
{
//llwarns << "GL used while not active!" << llendl;
if (gDebugSession)
{
//ll_fail("GL used while not active");
}
}
if (!gNoRender && gDebugGL)
{
do_assert_glerror();
}
}
void clear_glerror()
{
// Create or update texture to be used with this data
@ -1089,7 +1130,7 @@ void clear_glerror()
//
// Static members
std::map<LLGLenum, LLGLboolean> LLGLState::sStateMap;
boost::unordered_map<LLGLenum, LLGLboolean> LLGLState::sStateMap;
GLboolean LLGLDepthTest::sDepthEnabled = GL_FALSE; // OpenGL default
GLenum LLGLDepthTest::sDepthFunc = GL_LESS; // OpenGL default
@ -1137,7 +1178,7 @@ void LLGLState::resetTextureStates()
void LLGLState::dumpStates()
{
LL_INFOS("RenderState") << "GL States:" << LL_ENDL;
for (std::map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
for (boost::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
iter != sStateMap.end(); ++iter)
{
LL_INFOS("RenderState") << llformat(" 0x%04x : %s",(S32)iter->first,iter->second?"TRUE":"FALSE") << LL_ENDL;
@ -1173,7 +1214,7 @@ void LLGLState::checkStates(const std::string& msg)
}
}
for (std::map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
for (boost::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
iter != sStateMap.end(); ++iter)
{
LLGLenum state = iter->first;

View File

@ -30,7 +30,7 @@
// This file contains various stuff for handling gl extensions and other gl related stuff.
#include <string>
#include <map>
#include <boost/unordered_map.hpp>
#include <list>
#include "llerror.h"
@ -81,6 +81,7 @@ public:
BOOL mHasCompressedTextures;
BOOL mHasFramebufferObject;
BOOL mHasFramebufferMultisample;
BOOL mHasBlendFuncSeparate;
// ARB Extensions
BOOL mHasVertexBufferObject;
@ -113,6 +114,9 @@ public:
// Misc extensions
BOOL mHasSeparateSpecularColor;
//whether this GPU is in the debug list.
BOOL mDebugGPU;
S32 mDriverVersionMajor;
S32 mDriverVersionMinor;
@ -141,6 +145,7 @@ private:
void initExtensions();
void initGLStates();
void initGLImages();
void setToDebugGPU();
};
extern LLGLManager gGLManager;
@ -234,7 +239,7 @@ public:
static void checkClientArrays(const std::string& msg = "", U32 data_mask = 0x0001);
protected:
static std::map<LLGLenum, LLGLboolean> sStateMap;
static boost::unordered_map<LLGLenum, LLGLboolean> sStateMap;
public:
enum { CURRENT_STATE = -2 };

View File

@ -210,6 +210,9 @@ extern PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glGetCompressedTexImageARB;
extern PFNGLCOLORTABLEEXTPROC glColorTableEXT;
//GL_EXT_blend_func_separate
extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT;
//GL_EXT_framebuffer_object
extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT;
extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT;
@ -243,7 +246,10 @@ extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;
# include "GL/glh_extensions.h"
# undef __APPLE__
#elif LL_LINUX
#elif LL_LINUX
//----------------------------------------------------------------------------
// LL_LINUX
//----------------------------------------------------------------------------
// Linux, MESA headers, but not necessarily assuming MESA runtime.
// quotes so we get libraries/.../GL/ version
@ -279,6 +285,7 @@ extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;
# define LL_LINUX_NV_GL_HEADERS 0
#endif // LL_LINUX && defined(WINGDIAPI)
#if LL_LINUX_NV_GL_HEADERS
// Missing functions when using nvidia headers:
extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
@ -439,6 +446,9 @@ extern PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB;
extern PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB;
extern PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glGetCompressedTexImageARB;
//GL_EXT_blend_func_separate
extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT;
//GL_EXT_framebuffer_object
extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT;
extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT;
@ -467,7 +477,10 @@ extern PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT;
//GL_ARB_draw_buffers
extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;
#elif LL_WINDOWS
//----------------------------------------------------------------------------
// LL_WINDOWS
// windows gl headers depend on things like APIENTRY, so include windows.
#define WIN32_LEAN_AND_MEAN
@ -635,6 +648,9 @@ extern PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocationARB;
extern PFNGLGETACTIVEATTRIBARBPROC glGetActiveAttribARB;
extern PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB;
//GL_EXT_blend_func_separate
extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT;
//GL_EXT_framebuffer_object
extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT;
extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT;
@ -663,6 +679,7 @@ extern PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT;
//GL_ARB_draw_buffers
extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;
#elif LL_DARWIN
//----------------------------------------------------------------------------
// LL_DARWIN
@ -679,6 +696,9 @@ extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;
// Note that they also must not be called on 10.3.9. This should be taken care of by a runtime check for the existence of the GL extension.
#include <AvailabilityMacros.h>
//GL_EXT_blend_func_separate
extern void glBlendFuncSeparateEXT(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
// GL_EXT_framebuffer_object
extern GLboolean glIsRenderbufferEXT(GLuint renderbuffer) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
extern void glBindRenderbufferEXT(GLenum target, GLuint renderbuffer) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;

View File

@ -144,12 +144,12 @@ void LLImageGL::checkTexSize(bool forced) const
if (gDebugSession)
{
gFailLog << "wrong texture size and discard level!" <<
mWidth << " Height: " << mHeight << " Current Level: " << mCurrentDiscardLevel << std::endl;
mWidth << " Height: " << mHeight << " Current Level: " << (S32)mCurrentDiscardLevel << std::endl;
}
else
{
llerrs << "wrong texture size and discard level: width: " <<
mWidth << " Height: " << mHeight << " Current Level: " << mCurrentDiscardLevel << llendl ;
mWidth << " Height: " << mHeight << " Current Level: " << (S32)mCurrentDiscardLevel << llendl ;
}
}
@ -1051,8 +1051,12 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
{
if (gGL.getTexUnit(0)->bind(this, false, true))
{
checkTexSize(true) ;
llcallstacks << fb_x << " : " << fb_y << " : " << x_pos << " : " << y_pos << " : " << width << " : " << height << llcallstacksendl ;
if(gGLManager.mDebugGPU)
{
llinfos << "Calling glCopyTexSubImage2D(...)" << llendl ;
checkTexSize(true) ;
llcallstacks << fb_x << " : " << fb_y << " : " << x_pos << " : " << y_pos << " : " << width << " : " << height << llcallstacksendl ;
}
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height);
mGLTextureCreated = true;
@ -1648,7 +1652,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()
}
}
void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h)
void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
{
if(!mNeedsAlphaAndPickMask)
{
@ -1656,26 +1660,91 @@ void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h)
}
U32 length = w * h;
const GLubyte* current = ((const GLubyte*) data_in) + mAlphaOffset ;
U32 alphatotal = 0;
S32 sample[16];
memset(sample, 0, sizeof(S32)*16);
U32 sample[16];
memset(sample, 0, sizeof(U32)*16);
for (U32 i = 0; i < length; i++)
// generate histogram of quantized alpha.
// also add-in the histogram of a 2x2 box-sampled version. The idea is
// this will mid-skew the data (and thus increase the chances of not
// being used as a mask) from high-frequency alpha maps which
// suffer the worst from aliasing when used as alpha masks.
if (w >= 2 && h >= 2)
{
++sample[*current/16];
current += mAlphaStride ;
}
llassert(w%2 == 0);
llassert(h%2 == 0);
const GLubyte* rowstart = ((const GLubyte*) data_in) + mAlphaOffset;
for (U32 y = 0; y < h; y+=2)
{
const GLubyte* current = rowstart;
for (U32 x = 0; x < w; x+=2)
{
const U32 s1 = current[0];
alphatotal += s1;
const U32 s2 = current[w * mAlphaStride];
alphatotal += s2;
current += mAlphaStride;
const U32 s3 = current[0];
alphatotal += s3;
const U32 s4 = current[w * mAlphaStride];
alphatotal += s4;
current += mAlphaStride;
U32 total = 0;
++sample[s1/16];
++sample[s2/16];
++sample[s3/16];
++sample[s4/16];
const U32 asum = (s1+s2+s3+s4);
alphatotal += asum;
sample[asum/(16*4)] += 4;
}
rowstart += 2 * w * mAlphaStride;
}
length *= 2; // we sampled everything twice, essentially
}
else
{
const GLubyte* current = ((const GLubyte*) data_in) + mAlphaOffset;
for (U32 i = 0; i < length; i++)
{
const U32 s1 = *current;
alphatotal += s1;
++sample[s1/16];
current += mAlphaStride;
}
}
// if more than 1/16th of alpha samples are mid-range, this
// shouldn't be treated as a 1-bit mask
// also, if all of the alpha samples are clumped on one half
// of the range (but not at an absolute extreme), then consider
// this to be an intentional effect and don't treat as a mask.
U32 midrangetotal = 0;
for (U32 i = 4; i < 11; i++)
{
total += sample[i];
midrangetotal += sample[i];
}
U32 lowerhalftotal = 0;
for (U32 i = 0; i < 8; i++)
{
lowerhalftotal += sample[i];
}
U32 upperhalftotal = 0;
for (U32 i = 8; i < 16; i++)
{
upperhalftotal += sample[i];
}
if (total > length/16)
if (midrangetotal > length/16 || // lots of midrange, or
(lowerhalftotal == length && alphatotal != 0) || // all close to transparent but not all totally transparent, or
(upperhalftotal == length && alphatotal != 255*length)) // all close to opaque but not all totally opaque
{
mIsMask = FALSE;
mIsMask = FALSE; // not suitable for masking
}
else
{

View File

@ -85,7 +85,7 @@ public:
protected:
virtual ~LLImageGL();
void analyzeAlpha(const void* data_in, S32 w, S32 h);
void analyzeAlpha(const void* data_in, U32 w, U32 h);
void calcAlphaChannelOffsetAndStride();
public:

View File

@ -772,8 +772,10 @@ LLRender::LLRender()
mCurrAlphaFunc = CF_DEFAULT;
mCurrAlphaFuncVal = 0.01f;
mCurrBlendSFactor = BF_UNDEF;
mCurrBlendDFactor = BF_UNDEF;
mCurrBlendColorSFactor = BF_UNDEF;
mCurrBlendAlphaSFactor = BF_UNDEF;
mCurrBlendColorDFactor = BF_UNDEF;
mCurrBlendAlphaDFactor = BF_UNDEF;
}
LLRender::~LLRender()
@ -843,9 +845,9 @@ void LLRender::translateUI(F32 x, F32 y, F32 z)
llerrs << "Need to push a UI translation frame before offsetting" << llendl;
}
mUIOffset.front().mV[0] += x;
mUIOffset.front().mV[1] += y;
mUIOffset.front().mV[2] += z;
mUIOffset.back().mV[0] += x;
mUIOffset.back().mV[1] += y;
mUIOffset.back().mV[2] += z;
}
void LLRender::scaleUI(F32 x, F32 y, F32 z)
@ -855,27 +857,27 @@ void LLRender::scaleUI(F32 x, F32 y, F32 z)
llerrs << "Need to push a UI transformation frame before scaling." << llendl;
}
mUIScale.front().scaleVec(LLVector3(x,y,z));
mUIScale.back().scaleVec(LLVector3(x,y,z));
}
void LLRender::pushUIMatrix()
{
if (mUIOffset.empty())
{
mUIOffset.push_front(LLVector3(0,0,0));
mUIOffset.push_back(LLVector3(0,0,0));
}
else
{
mUIOffset.push_front(mUIOffset.front());
mUIOffset.push_back(mUIOffset.back());
}
if (mUIScale.empty())
{
mUIScale.push_front(LLVector3(1,1,1));
mUIScale.push_back(LLVector3(1,1,1));
}
else
{
mUIScale.push_front(mUIScale.front());
mUIScale.push_back(mUIScale.back());
}
}
@ -885,26 +887,26 @@ void LLRender::popUIMatrix()
{
llerrs << "UI offset stack blown." << llendl;
}
mUIOffset.pop_front();
mUIScale.pop_front();
mUIOffset.pop_back();
mUIScale.pop_back();
}
LLVector3 LLRender::getUITranslation()
{
if (mUIOffset.empty())
{
llerrs << "UI offset stack empty." << llendl;
return LLVector3::zero;
}
return mUIOffset.front();
return mUIOffset.back();
}
LLVector3 LLRender::getUIScale()
{
if (mUIScale.empty())
{
llerrs << "UI scale stack empty." << llendl;
return LLVector3(1.f, 1.f, 1.f);
}
return mUIScale.front();
return mUIScale.back();
}
@ -914,8 +916,8 @@ void LLRender::loadUIIdentity()
{
llerrs << "Need to push UI translation frame before clearing offset." << llendl;
}
mUIOffset.front().setVec(0,0,0);
mUIScale.front().setVec(1,1,1);
mUIOffset.back().setVec(0,0,0);
mUIScale.back().setVec(1,1,1);
}
void LLRender::setColorMask(bool writeColor, bool writeAlpha)
@ -989,15 +991,44 @@ void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor)
{
llassert(sfactor < BF_UNDEF);
llassert(dfactor < BF_UNDEF);
if (mCurrBlendSFactor != sfactor || mCurrBlendDFactor != dfactor)
if (mCurrBlendColorSFactor != sfactor || mCurrBlendColorDFactor != dfactor ||
mCurrBlendAlphaSFactor != sfactor || mCurrBlendAlphaDFactor != dfactor)
{
mCurrBlendSFactor = sfactor;
mCurrBlendDFactor = dfactor;
mCurrBlendColorSFactor = sfactor;
mCurrBlendAlphaSFactor = sfactor;
mCurrBlendColorDFactor = dfactor;
mCurrBlendAlphaDFactor = dfactor;
flush();
glBlendFunc(sGLBlendFactor[sfactor], sGLBlendFactor[dfactor]);
}
}
void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor,
eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor)
{
llassert(color_sfactor < BF_UNDEF);
llassert(color_dfactor < BF_UNDEF);
llassert(alpha_sfactor < BF_UNDEF);
llassert(alpha_dfactor < BF_UNDEF);
if (!gGLManager.mHasBlendFuncSeparate)
{
LL_WARNS_ONCE("render") << "no glBlendFuncSeparateEXT(), using color-only blend func" << llendl;
blendFunc(color_sfactor, color_dfactor);
return;
}
if (mCurrBlendColorSFactor != color_sfactor || mCurrBlendColorDFactor != color_dfactor ||
mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor)
{
mCurrBlendColorSFactor = color_sfactor;
mCurrBlendAlphaSFactor = alpha_sfactor;
mCurrBlendColorDFactor = color_dfactor;
mCurrBlendAlphaDFactor = alpha_dfactor;
flush();
glBlendFuncSeparateEXT(sGLBlendFactor[color_sfactor], sGLBlendFactor[color_dfactor],
sGLBlendFactor[alpha_sfactor], sGLBlendFactor[alpha_dfactor]);
}
}
LLTexUnit* LLRender::getTexUnit(U32 index)
{
if (index < mTexUnits.size())
@ -1173,18 +1204,79 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
}
else
{
LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.front()).scaledVec(mUIScale.front());
LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.back()).scaledVec(mUIScale.back());
mVerticesp[mCount] = vert;
}
mCount++;
if (mCount < 4096)
{
mVerticesp[mCount] = mVerticesp[mCount-1];
mColorsp[mCount] = mColorsp[mCount-1];
mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
}
mVerticesp[mCount] = mVerticesp[mCount-1];
mColorsp[mCount] = mColorsp[mCount-1];
mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
}
void LLRender::vertexBatchPreTransformed(LLVector3* verts, S32 vert_count)
{
if (mCount + vert_count > 4094)
{
// llwarns << "GL immediate mode overflow. Some geometry not drawn." << llendl;
return;
}
for (S32 i = 0; i < vert_count; i++)
{
mVerticesp[mCount] = verts[i];
mCount++;
mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
mColorsp[mCount] = mColorsp[mCount-1];
}
mVerticesp[mCount] = mVerticesp[mCount-1];
}
void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count)
{
if (mCount + vert_count > 4094)
{
// llwarns << "GL immediate mode overflow. Some geometry not drawn." << llendl;
return;
}
for (S32 i = 0; i < vert_count; i++)
{
mVerticesp[mCount] = verts[i];
mTexcoordsp[mCount] = uvs[i];
mCount++;
mColorsp[mCount] = mColorsp[mCount-1];
}
mVerticesp[mCount] = mVerticesp[mCount-1];
mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
}
void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U* colors, S32 vert_count)
{
if (mCount + vert_count > 4094)
{
// llwarns << "GL immediate mode overflow. Some geometry not drawn." << llendl;
return;
}
for (S32 i = 0; i < vert_count; i++)
{
mVerticesp[mCount] = verts[i];
mTexcoordsp[mCount] = uvs[i];
mColorsp[mCount] = colors[i];
mCount++;
}
mVerticesp[mCount] = mVerticesp[mCount-1];
mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
mColorsp[mCount] = mColorsp[mCount-1];
}
void LLRender::vertex2i(const GLint& x, const GLint& y)
{
vertex3f((GLfloat) x, (GLfloat) y, 0);

View File

@ -311,13 +311,21 @@ public:
void color3fv(const GLfloat* c);
void color4ubv(const GLubyte* c);
void vertexBatchPreTransformed(LLVector3* verts, S32 vert_count);
void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count);
void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U*, S32 vert_count);
void setColorMask(bool writeColor, bool writeAlpha);
void setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha);
void setSceneBlendType(eBlendType type);
void setAlphaRejectSettings(eCompareFunc func, F32 value = 0.01f);
// applies blend func to both color and alpha
void blendFunc(eBlendFactor sfactor, eBlendFactor dfactor);
// applies separate blend functions to color and alpha
void blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor,
eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor);
LLTexUnit* getTexUnit(U32 index);
@ -356,13 +364,15 @@ private:
std::vector<LLTexUnit*> mTexUnits;
LLTexUnit* mDummyTexUnit;
eBlendFactor mCurrBlendSFactor;
eBlendFactor mCurrBlendDFactor;
eBlendFactor mCurrBlendColorSFactor;
eBlendFactor mCurrBlendColorDFactor;
eBlendFactor mCurrBlendAlphaSFactor;
eBlendFactor mCurrBlendAlphaDFactor;
F32 mMaxAnisotropy;
std::list<LLVector3> mUIOffset;
std::list<LLVector3> mUIScale;
std::vector<LLVector3> mUIOffset;
std::vector<LLVector3> mUIScale;
};

View File

@ -376,6 +376,11 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
{
mUsage = 0 ;
}
if (mUsage == GL_STREAM_DRAW_ARB && !sUseStreamDraw)
{
mUsage = 0;
}
if (mUsage == GL_STREAM_DRAW_ARB && !sUseStreamDraw)
{

View File

@ -133,7 +133,7 @@ public:
*/
const LLAccordionCtrlTab* getExpandedTab() const;
const LLAccordionCtrlTab* getSelectedTab() const { return mSelectedTab; }
LLAccordionCtrlTab* getSelectedTab() const { return mSelectedTab; }
bool getFitParent() const {return mFitParent;}

View File

@ -353,6 +353,7 @@ LLAccordionCtrlTab::LLAccordionCtrlTab(const LLAccordionCtrlTab::Params&p)
,mPaddingBottom(p.padding_bottom)
,mCanOpenClose(true)
,mFitPanel(p.fit_panel)
,mSelectionEnabled(p.selection_enabled)
,mContainerPanel(NULL)
,mScrollbar(NULL)
{
@ -824,7 +825,7 @@ void LLAccordionCtrlTab::showAndFocusHeader()
{
LLAccordionCtrlTabHeader* header = getChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
header->setFocus(true);
header->setSelected(true);
header->setSelected(mSelectionEnabled);
LLRect screen_rc;
LLRect selected_rc = header->getRect();

View File

@ -236,6 +236,8 @@ private:
bool mStoredOpenCloseState;
bool mWasStateStored;
bool mSelectionEnabled;
LLScrollbar* mScrollbar;
LLView* mContainerPanel;

View File

@ -114,6 +114,7 @@ LLButton::LLButton(const LLButton::Params& p)
mFlashing( FALSE ),
mCurGlowStrength(0.f),
mNeedsHighlight(FALSE),
mMouseOver(false),
mUnselectedLabel(p.label()),
mSelectedLabel(p.label_selected()),
mGLFont(p.font),
@ -498,7 +499,11 @@ void LLButton::onMouseEnter(S32 x, S32 y, MASK mask)
LLUICtrl::onMouseEnter(x, y, mask);
if (isInEnabledChain())
{
mNeedsHighlight = TRUE;
}
mMouseOver = true;
}
void LLButton::onMouseLeave(S32 x, S32 y, MASK mask)
@ -506,6 +511,7 @@ void LLButton::onMouseLeave(S32 x, S32 y, MASK mask)
LLUICtrl::onMouseLeave(x, y, mask);
mNeedsHighlight = FALSE;
mMouseOver = true;
}
void LLButton::setHighlight(bool b)
@ -559,14 +565,10 @@ void LLButton::draw()
}
// Unselected image assignments
S32 local_mouse_x;
S32 local_mouse_y;
LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y);
bool enabled = isInEnabledChain();
bool pressed = pressed_by_keyboard
|| (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y))
|| (hasMouseCapture() && mMouseOver)
|| mForcePressedState;
bool selected = getToggleState();

View File

@ -350,6 +350,7 @@ private:
BOOL mCommitOnReturn;
BOOL mFadeWhenDisabled;
bool mForcePressedState;
bool mMouseOver;
LLFrameTimer mFlashingTimer;
};

View File

@ -29,12 +29,13 @@
#include <map>
#include <string>
#include <boost/function.hpp>
class LLCallbackMap
{
public:
// callback definition.
typedef void* (*callback_t)(void* data);
typedef boost::function<void* (void* data)> callback_t;
typedef std::map<std::string, LLCallbackMap> map_t;
typedef map_t::iterator map_iter_t;

View File

@ -43,12 +43,13 @@ void LLDockableFloater::init(LLDockableFloater* thiz)
thiz->setCanClose(TRUE);
thiz->setCanDock(true);
thiz->setCanMinimize(TRUE);
thiz->setOverlapsScreenChannel(false);
thiz->mForceDocking = false;
}
LLDockableFloater::LLDockableFloater(LLDockControl* dockControl,
const LLSD& key, const Params& params) :
LLFloater(key, params), mDockControl(dockControl), mUniqueDocking(true)
, mOverlapsScreenChannel(false)
{
init(this);
mUseTongue = true;
@ -75,6 +76,12 @@ LLDockableFloater::~LLDockableFloater()
BOOL LLDockableFloater::postBuild()
{
// Remember we should force docking when the floater is opened for the first time
if (mIsDockedStateForcedCallback != NULL && mIsDockedStateForcedCallback())
{
mForceDocking = true;
}
mDockTongue = LLUI::getUIImage("windows/Flyout_Pointer.png");
LLFloater::setDocked(true);
return LLView::postBuild();
@ -128,6 +135,14 @@ void LLDockableFloater::resetInstance()
void LLDockableFloater::setVisible(BOOL visible)
{
// Force docking if requested
if (visible && mForceDocking)
{
setCanDock(true);
setDocked(true);
mForceDocking = false;
}
if(visible && isDocked())
{
resetInstance();

View File

@ -124,6 +124,10 @@ protected:
void setDockControl(LLDockControl* dockControl);
const LLUIImagePtr& getDockTongue();
// Checks if docking should be forced.
// It may be useful e.g. if floater created in mouselook mode (see EXT-5609)
boost::function<BOOL ()> mIsDockedStateForcedCallback;
private:
std::auto_ptr<LLDockControl> mDockControl;
LLUIImagePtr mDockTongue;
@ -137,6 +141,9 @@ private:
bool mUseTongue;
bool mOverlapsScreenChannel;
// Force docking when the floater is being shown for the first time.
bool mForceDocking;
};
#endif /* LL_DOCKABLEFLOATER_H */

View File

@ -107,7 +107,7 @@ void LLDragHandleTop::setTitle(const std::string& title)
params.follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT | FOLLOWS_RIGHT);
params.font_shadow(LLFontGL::DROP_SHADOW_SOFT);
params.use_ellipses = true;
params.allow_html = false; //cancel URL replacement in floater title
params.parse_urls = false; //cancel URL replacement in floater title
mTitleBox = LLUICtrlFactory::create<LLTextBox> (params);
addChild( mTitleBox );
}

View File

@ -607,8 +607,14 @@ void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask)
return;
}
if (!(mask & MASK_CONTROL) || !mMultipleSelection) resetSelection();
//no need to do additional commit on selection reset
if (!(mask & MASK_CONTROL) || !mMultipleSelection) resetSelection(true);
//only CTRL usage allows to deselect an item, usual clicking on an item cannot deselect it
if (mask & MASK_CONTROL)
selectItemPair(item_pair, select_item);
else
selectItemPair(item_pair, true);
}
void LLFlatListView::onItemRightMouseClick(item_pair_t* item_pair, MASK mask)
@ -660,6 +666,14 @@ BOOL LLFlatListView::handleKeyHere(KEY key, MASK mask)
}
break;
}
case KEY_ESCAPE:
{
if (mask == MASK_NONE)
{
setFocus(FALSE); // pass focus to the game area (EXT-8357)
}
break;
}
default:
break;
}
@ -775,6 +789,18 @@ bool LLFlatListView::selectItemPair(item_pair_t* item_pair, bool select)
return true;
}
void LLFlatListView::scrollToShowFirstSelectedItem()
{
if (!mSelectedItemPairs.size()) return;
LLRect selected_rc = mSelectedItemPairs.front()->first->getRect();
if (selected_rc.isValid())
{
scrollToShowRect(selected_rc);
}
}
LLRect LLFlatListView::getLastSelectedItemRect()
{
if (!mSelectedItemPairs.size())

View File

@ -292,6 +292,7 @@ public:
bool updateValue(const LLSD& old_value, const LLSD& new_value);
void scrollToShowFirstSelectedItem();
void selectFirstItem ();
void selectLastItem ();

View File

@ -2279,6 +2279,7 @@ void LLFloaterView::getMinimizePosition(S32 *left, S32 *bottom)
S32 floater_header_size = default_params.header_height;
static LLUICachedControl<S32> minimized_width ("UIMinimizedWidth", 0);
LLRect snap_rect_local = getLocalSnapRect();
snap_rect_local.mTop += mMinimizePositionVOffset;
for(S32 col = snap_rect_local.mLeft;
col < snap_rect_local.getWidth() - minimized_width;
col += minimized_width)
@ -2376,6 +2377,19 @@ BOOL LLFloaterView::allChildrenClosed()
return true;
}
void LLFloaterView::shiftFloaters(S32 x_offset, S32 y_offset)
{
for (child_list_const_iter_t it = getChildList()->begin(); it != getChildList()->end(); ++it)
{
LLFloater* floaterp = dynamic_cast<LLFloater*>(*it);
if (floaterp && floaterp->isMinimized())
{
floaterp->translate(x_offset, y_offset);
}
}
}
void LLFloaterView::refresh()
{
// Constrain children to be entirely on the screen

View File

@ -449,6 +449,7 @@ public:
// Given a child of gFloaterView, make sure this view can fit entirely onscreen.
void adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside);
void setMinimizePositionVerticalOffset(S32 offset) { mMinimizePositionVOffset = offset; }
void getMinimizePosition( S32 *left, S32 *bottom);
void restoreAll(); // un-minimize all floaters
typedef std::set<LLView*> skip_list_t;
@ -465,6 +466,7 @@ public:
// attempt to close all floaters
void closeAllChildren(bool app_quitting);
BOOL allChildrenClosed();
void shiftFloaters(S32 x_offset, S32 y_offset);
LLFloater* getFrontmost() const;
LLFloater* getBackmost() const;
@ -484,6 +486,7 @@ private:
BOOL mFocusCycleMode;
S32 mSnapOffsetBottom;
S32 mSnapOffsetRight;
S32 mMinimizePositionVOffset;
};
//

View File

@ -27,33 +27,8 @@
#include "lllocalcliprect.h"
#include "llfontgl.h"
#include "llgl.h"
#include "llui.h"
#include <stack>
//---------------------------------------------------------------------------
// LLScreenClipRect
// implementation class in screen space
//---------------------------------------------------------------------------
class LLScreenClipRect
{
public:
LLScreenClipRect(const LLRect& rect, BOOL enabled = TRUE);
virtual ~LLScreenClipRect();
private:
static void pushClipRect(const LLRect& rect);
static void popClipRect();
static void updateScissorRegion();
private:
LLGLState mScissorState;
BOOL mEnabled;
static std::stack<LLRect> sClipRectStack;
};
/*static*/ std::stack<LLRect> LLScreenClipRect::sClipRectStack;
@ -64,9 +39,9 @@ LLScreenClipRect::LLScreenClipRect(const LLRect& rect, BOOL enabled)
if (mEnabled)
{
pushClipRect(rect);
mScissorState.setEnabled(!sClipRectStack.empty());
updateScissorRegion();
}
mScissorState.setEnabled(!sClipRectStack.empty());
updateScissorRegion();
}
LLScreenClipRect::~LLScreenClipRect()
@ -74,8 +49,8 @@ LLScreenClipRect::~LLScreenClipRect()
if (mEnabled)
{
popClipRect();
updateScissorRegion();
}
updateScissorRegion();
}
//static
@ -125,16 +100,11 @@ void LLScreenClipRect::updateScissorRegion()
// LLLocalClipRect
//---------------------------------------------------------------------------
LLLocalClipRect::LLLocalClipRect(const LLRect& rect, BOOL enabled /* = TRUE */)
{
LLRect screen(rect.mLeft + LLFontGL::sCurOrigin.mX,
rect.mTop + LLFontGL::sCurOrigin.mY,
rect.mRight + LLFontGL::sCurOrigin.mX,
rect.mBottom + LLFontGL::sCurOrigin.mY);
mScreenClipRect = new LLScreenClipRect(screen, enabled);
}
: LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX,
rect.mTop + LLFontGL::sCurOrigin.mY,
rect.mRight + LLFontGL::sCurOrigin.mX,
rect.mBottom + LLFontGL::sCurOrigin.mY), enabled)
{}
LLLocalClipRect::~LLLocalClipRect()
{
delete mScreenClipRect;
mScreenClipRect = NULL;
}
{}

View File

@ -25,7 +25,9 @@
#ifndef LLLOCALCLIPRECT_H
#define LLLOCALCLIPRECT_H
#include "llgl.h"
#include "llrect.h" // can't forward declare, it's templated
#include <stack>
// Clip rendering to a specific rectangle using GL scissor
// Just create one of these on the stack:
@ -33,15 +35,29 @@
// LLLocalClipRect(rect);
// draw();
// }
class LLLocalClipRect
class LLScreenClipRect
{
public:
LLScreenClipRect(const LLRect& rect, BOOL enabled = TRUE);
virtual ~LLScreenClipRect();
private:
static void pushClipRect(const LLRect& rect);
static void popClipRect();
static void updateScissorRegion();
private:
LLGLState mScissorState;
BOOL mEnabled;
static std::stack<LLRect> sClipRectStack;
};
class LLLocalClipRect : public LLScreenClipRect
{
public:
LLLocalClipRect(const LLRect& rect, BOOL enabled = TRUE);
~LLLocalClipRect();
private:
// implementation class
class LLScreenClipRect* mScreenClipRect;
};
#endif

View File

@ -52,6 +52,7 @@
#include "llbutton.h"
#include "llfontgl.h"
#include "llresmgr.h"
#include "lltrans.h"
#include "llui.h"
#include "llstl.h"
@ -2266,8 +2267,9 @@ void LLMenuGL::createSpilloverBranch()
// technically, you can't tear off spillover menus, but we're passing the handle
// along just to be safe
LLMenuGL::Params p;
std::string label = LLTrans::getString("More");
p.name("More");
p.label("More"); // *TODO: Translate
p.label(label);
p.bg_color(mBackgroundColor);
p.bg_visible(true);
p.can_tear_off(false);
@ -2276,7 +2278,7 @@ void LLMenuGL::createSpilloverBranch()
LLMenuItemBranchGL::Params branch_params;
branch_params.name = "More";
branch_params.label = "More"; // *TODO: Translate
branch_params.label = label;
branch_params.branch = mSpilloverMenu;
branch_params.font.style = "italic";

View File

@ -655,7 +655,7 @@ void LLPanel::childSetEnabled(const std::string& id, bool enabled)
void LLPanel::childSetTentative(const std::string& id, bool tentative)
{
LLView* child = findChild<LLView>(id);
LLUICtrl* child = findChild<LLUICtrl>(id);
if (child)
{
child->setTentative(tentative);
@ -854,13 +854,16 @@ LLPanel *LLPanel::childGetVisibleTab(const std::string& id) const
return NULL;
}
static LLPanel *childGetVisibleTabWithHelp(LLView *parent)
LLPanel* LLPanel::childGetVisibleTabWithHelp()
{
LLView *child;
// look through immediate children first for an active tab with help
for (child = parent->getFirstChild(); child; child = parent->findNextSibling(child))
bfs_tree_iterator_t it = beginTreeBFS();
// skip ourselves
++it;
for (; it != endTreeBFS(); ++it)
{
child = *it;
LLPanel *curTabPanel = NULL;
// do we have a tab container?
@ -884,36 +887,21 @@ static LLPanel *childGetVisibleTabWithHelp(LLView *parent)
}
}
// then try a bit harder and recurse through all children
for (child = parent->getFirstChild(); child; child = parent->findNextSibling(child))
{
if (child->getVisible())
{
LLPanel* tab = ::childGetVisibleTabWithHelp(child);
if (tab)
{
return tab;
}
}
}
// couldn't find any active tabs with a help topic string
return NULL;
}
LLPanel *LLPanel::childGetVisibleTabWithHelp()
{
// find a visible tab with a help topic (to determine help context)
return ::childGetVisibleTabWithHelp(this);
}
static LLPanel *childGetVisiblePanelWithHelp(LLView *parent)
LLPanel *LLPanel::childGetVisiblePanelWithHelp()
{
LLView *child;
// look through immediate children first for an active panel with help
for (child = parent->getFirstChild(); child; child = parent->findNextSibling(child))
bfs_tree_iterator_t it = beginTreeBFS();
// skip ourselves
++it;
for (; it != endTreeBFS(); ++it)
{
child = *it;
// do we have a panel with a help topic?
LLPanel *panel = dynamic_cast<LLPanel *>(child);
if (panel && panel->getVisible() && !panel->getHelpTopic().empty())
@ -922,39 +910,19 @@ static LLPanel *childGetVisiblePanelWithHelp(LLView *parent)
}
}
// then try a bit harder and recurse through all children
for (child = parent->getFirstChild(); child; child = parent->findNextSibling(child))
{
if (child->getVisible())
{
LLPanel* panel = ::childGetVisiblePanelWithHelp(child);
if (panel)
{
return panel;
}
}
}
// couldn't find any active panels with a help topic string
return NULL;
}
LLPanel *LLPanel::childGetVisiblePanelWithHelp()
void LLPanel::childSetAction(const std::string& id, const commit_signal_t::slot_type& function)
{
// find a visible tab with a help topic (to determine help context)
return ::childGetVisiblePanelWithHelp(this);
}
void LLPanel::childSetPrevalidate(const std::string& id, bool (*func)(const LLWString &) )
{
LLLineEditor* child = findChild<LLLineEditor>(id);
if (child)
LLButton* button = findChild<LLButton>(id);
if (button)
{
child->setPrevalidate(func);
button->setClickedCallback(function);
}
}
void LLPanel::childSetAction(const std::string& id, boost::function<void(void*)> function, void* value)
{
LLButton* button = findChild<LLButton>(id);

View File

@ -164,6 +164,7 @@ public:
std::string getString(const std::string& name) const;
// ** Wrappers for setting child properties by name ** -TomY
// WARNING: These are deprecated, please use getChild<T>("name")->doStuff() idiom instead
// LLView
void childSetVisible(const std::string& name, bool visible);
@ -227,7 +228,8 @@ public:
void childSetPrevalidate(const std::string& id, bool (*func)(const LLWString &) );
// LLButton
void childSetAction(const std::string& id, boost::function<void(void*)> function, void* value = NULL);
void childSetAction(const std::string& id, boost::function<void(void*)> function, void* value);
void childSetAction(const std::string& id, const commit_signal_t::slot_type& function);
// LLTextBox
void childSetActionTextbox(const std::string& id, boost::function<void(void*)> function, void* value = NULL);

View File

@ -129,6 +129,7 @@ LLScrollListCtrl::Params::Params()
search_column("search_column", 0),
sort_column("sort_column", -1),
sort_ascending("sort_ascending", true),
mouse_wheel_opaque("mouse_wheel_opaque", false),
commit_on_keyboard_movement("commit_on_keyboard_movement", true),
heading_height("heading_height"),
page_lines("page_lines", 0),
@ -157,6 +158,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
: LLUICtrl(p),
mLineHeight(0),
mScrollLines(0),
mMouseWheelOpaque(p.mouse_wheel_opaque),
mPageLines(p.page_lines),
mMaxSelectable(0),
mAllowKeyboardMovement(TRUE),
@ -1530,6 +1532,12 @@ BOOL LLScrollListCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks)
BOOL handled = FALSE;
// Pretend the mouse is over the scrollbar
handled = mScrollbar->handleScrollWheel( 0, 0, clicks );
if (mMouseWheelOpaque)
{
return TRUE;
}
return handled;
}

View File

@ -96,7 +96,8 @@ public:
{
// behavioral flags
Optional<bool> multi_select,
commit_on_keyboard_movement;
commit_on_keyboard_movement,
mouse_wheel_opaque;
// display flags
Optional<bool> has_border,
@ -443,6 +444,7 @@ private:
BOOL mCommitOnSelectionChange;
BOOL mSelectionChanged;
BOOL mNeedsScroll;
BOOL mMouseWheelOpaque;
BOOL mCanSelect;
const BOOL mDisplayColumnHeaders;
BOOL mColumnsDirty;

View File

@ -229,6 +229,10 @@ void LLSliderCtrl::updateText()
std::string text = llformat(format.c_str(), displayed_value);
if( mEditor )
{
// Setting editor text here to "" before using actual text is here because if text which
// is set is the same as the one which is actually typed into lineeditor, LLLineEditor::setText()
// will exit at it's beginning, so text for revert on escape won't be saved. (EXT-8536)
mEditor->setText( LLStringUtil::null );
mEditor->setText( text );
}
else

View File

@ -36,6 +36,8 @@ LLStyle::Params::Params()
: visible("visible", true),
drop_shadow("drop_shadow", LLFontGL::NO_SHADOW),
color("color", LLColor4::black),
readonly_color("readonly_color", LLColor4::black),
selected_color("selected_color", LLColor4::black),
font("font", LLFontGL::getFontMonospace()),
image("image"),
link_href("href")
@ -43,12 +45,10 @@ LLStyle::Params::Params()
LLStyle::LLStyle(const LLStyle::Params& p)
: mItalic(FALSE),
mBold(FALSE),
mUnderline(FALSE),
mVisible(p.visible),
mColor(p.color()),
mReadOnlyColor(p.readonly_color()),
: mVisible(p.visible),
mColor(p.color),
mReadOnlyColor(p.readonly_color),
mSelectedColor(p.selected_color),
mFont(p.font()),
mLink(p.link_href),
mDropShadow(p.drop_shadow),

View File

@ -41,7 +41,8 @@ public:
Optional<bool> visible;
Optional<LLFontGL::ShadowType> drop_shadow;
Optional<LLUIColor> color,
readonly_color;
readonly_color,
selected_color;
Optional<const LLFontGL*> font;
Optional<LLUIImage*> image;
Optional<std::string> link_href;
@ -49,11 +50,14 @@ public:
};
LLStyle(const Params& p = Params());
public:
const LLColor4& getColor() const { return mColor; }
void setColor(const LLColor4 &color) { mColor = color; }
const LLUIColor& getColor() const { return mColor; }
void setColor(const LLUIColor &color) { mColor = color; }
const LLColor4& getReadOnlyColor() const { return mReadOnlyColor; }
void setReadOnlyColor(const LLColor4& color) { mReadOnlyColor = color; }
const LLUIColor& getReadOnlyColor() const { return mReadOnlyColor; }
void setReadOnlyColor(const LLUIColor& color) { mReadOnlyColor = color; }
const LLUIColor& getSelectedColor() const { return mSelectedColor; }
void setSelectedColor(const LLUIColor& color) { mSelectedColor = color; }
BOOL isVisible() const;
void setVisible(BOOL is_visible);
@ -73,41 +77,36 @@ public:
BOOL isImage() const { return mImagep.notNull(); }
// inlined here to make it easier to compare to member data below. -MG
bool operator==(const LLStyle &rhs) const
{
return
mVisible == rhs.mVisible
&& mColor == rhs.mColor
&& mReadOnlyColor == rhs.mReadOnlyColor
&& mSelectedColor == rhs.mSelectedColor
&& mFont == rhs.mFont
&& mLink == rhs.mLink
&& mImagep == rhs.mImagep
&& mItalic == rhs.mItalic
&& mBold == rhs.mBold
&& mUnderline == rhs.mUnderline
&& mDropShadow == rhs.mDropShadow;
}
bool operator!=(const LLStyle& rhs) const { return !(*this == rhs); }
public:
BOOL mItalic;
BOOL mBold;
BOOL mUnderline;
LLFontGL::ShadowType mDropShadow;
protected:
~LLStyle() { }
private:
BOOL mVisible;
LLUIColor mColor;
LLUIColor mReadOnlyColor;
std::string mFontName;
const LLFontGL* mFont; // cached for performance
std::string mLink;
LLUIImagePtr mImagep;
BOOL mVisible;
LLUIColor mColor;
LLUIColor mReadOnlyColor;
LLUIColor mSelectedColor;
std::string mFontName;
const LLFontGL* mFont;
std::string mLink;
LLUIImagePtr mImagep;
};
typedef LLPointer<LLStyle> LLStyleSP;

View File

@ -149,6 +149,8 @@ LLTextBase::Params::Params()
bg_readonly_color("bg_readonly_color"),
bg_writeable_color("bg_writeable_color"),
bg_focus_color("bg_focus_color"),
text_selected_color("text_selected_color"),
bg_selected_color("bg_selected_color"),
allow_scroll("allow_scroll", true),
plain_text("plain_text",false),
track_end("track_end", false),
@ -161,11 +163,12 @@ LLTextBase::Params::Params()
font_shadow("font_shadow"),
wrap("wrap"),
use_ellipses("use_ellipses", false),
allow_html("allow_html", false),
parse_urls("parse_urls", false),
parse_highlights("parse_highlights", false)
{
addSynonym(track_end, "track_bottom");
addSynonym(wrap, "word_wrap");
addSynonym(parse_urls, "allow_html");
}
@ -184,6 +187,8 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mWriteableBgColor(p.bg_writeable_color),
mReadOnlyBgColor(p.bg_readonly_color),
mFocusBgColor(p.bg_focus_color),
mTextSelectedColor(p.text_selected_color),
mSelectedBGColor(p.bg_selected_color),
mReflowIndex(S32_MAX),
mCursorPos( 0 ),
mScrollNeeded(FALSE),
@ -203,7 +208,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mPlainText ( p.plain_text ),
mWordWrap(p.wrap),
mUseEllipses( p.use_ellipses ),
mParseHTML(p.allow_html),
mParseHTML(p.parse_urls),
mParseHighlights(p.parse_highlights),
mBGVisible(p.bg_visible),
mScroller(NULL),
@ -263,9 +268,6 @@ void LLTextBase::initFromParams(const LLTextBase::Params& p)
{
mReadOnly = p.read_only;
}
// HACK: text editors always need to be enabled so that we can scroll
LLView::setEnabled(true);
}
bool LLTextBase::truncate()
@ -295,11 +297,14 @@ bool LLTextBase::truncate()
const LLStyle::Params& LLTextBase::getDefaultStyleParams()
{
//FIXME: convert mDefaultStyle to a flyweight http://www.boost.org/doc/libs/1_40_0/libs/flyweight/doc/index.html
//and eliminate color member values
if (mStyleDirty)
{
mDefaultStyle
.color(LLUIColor(&mFgColor))
.color(LLUIColor(&mFgColor)) // pass linked color instead of copy of mFGColor
.readonly_color(LLUIColor(&mReadOnlyFgColor))
.selected_color(LLUIColor(&mTextSelectedColor))
.font(mDefaultFont)
.drop_shadow(mFontShadow);
mStyleDirty = false;
@ -397,7 +402,7 @@ void LLTextBase::drawSelectionBackground()
// Draw the selection box (we're using a box instead of reversing the colors on the selected text).
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
const LLColor4& color = mReadOnly ? mReadOnlyFgColor.get() : mFgColor.get();
const LLColor4& color = mSelectedBGColor;
F32 alpha = hasFocus() ? 0.7f : 0.3f;
alpha *= getDrawContext().mAlpha;
LLColor4 selection_color(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], alpha);
@ -437,7 +442,6 @@ void LLTextBase::drawCursor()
}
else
{
//segmentp = mSegments.back();
return;
}
@ -471,21 +475,8 @@ void LLTextBase::drawCursor()
{
LLColor4 text_color;
const LLFontGL* fontp;
if (segmentp)
{
text_color = segmentp->getColor();
fontp = segmentp->getStyle()->getFont();
}
else if (mReadOnly)
{
text_color = mReadOnlyFgColor.get();
fontp = mDefaultFont;
}
else
{
text_color = mFgColor.get();
fontp = mDefaultFont;
}
fontp->render(text, mCursorPos, cursor_rect,
LLColor4(1.f - text_color.mV[VRED], 1.f - text_color.mV[VGREEN], 1.f - text_color.mV[VBLUE], alpha),
LLFontGL::LEFT, mVAlign,
@ -1015,21 +1006,26 @@ void LLTextBase::draw()
if (mBGVisible)
{
// clip background rect against extents, if we support scrolling
LLLocalClipRect clip(doc_rect, mScroller != NULL);
LLRect bg_rect = mVisibleTextRect;
if (mScroller)
{
bg_rect.intersectWith(doc_rect);
}
LLColor4 bg_color = mReadOnly
? mReadOnlyBgColor.get()
: hasFocus()
? mFocusBgColor.get()
: mWriteableBgColor.get();
gl_rect_2d(mVisibleTextRect, bg_color, TRUE);
gl_rect_2d(doc_rect, bg_color, TRUE);
}
// draw document view
LLUICtrl::draw();
{
// only clip if we support scrolling (mScroller != NULL)
// only clip if we support scrolling...
// since convention is that text boxes never vertically truncate their contents
// regardless of rect bounds
LLLocalClipRect clip(doc_rect, mScroller != NULL);
drawSelectionBackground();
drawText();
@ -1493,23 +1489,32 @@ void LLTextBase::getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg
LLTextBase::segment_set_t::iterator LLTextBase::getSegIterContaining(S32 index)
{
static LLPointer<LLIndexSegment> index_segment = new LLIndexSegment();
if (index > getLength()) { return mSegments.end(); }
// when there are no segments, we return the end iterator, which must be checked by caller
if (mSegments.size() <= 1) { return mSegments.begin(); }
segment_set_t::iterator it = mSegments.upper_bound(new LLIndexSegment(index));
//FIXME: avoid operator new somehow (without running into refcount problems)
index_segment->setStart(index);
index_segment->setEnd(index);
segment_set_t::iterator it = mSegments.upper_bound(index_segment);
return it;
}
LLTextBase::segment_set_t::const_iterator LLTextBase::getSegIterContaining(S32 index) const
{
static LLPointer<LLIndexSegment> index_segment = new LLIndexSegment();
if (index > getLength()) { return mSegments.end(); }
// when there are no segments, we return the end iterator, which must be checked by caller
if (mSegments.size() <= 1) { return mSegments.begin(); }
LLTextBase::segment_set_t::const_iterator it = mSegments.upper_bound(new LLIndexSegment(index));
index_segment->setStart(index);
index_segment->setEnd(index);
LLTextBase::segment_set_t::const_iterator it = mSegments.upper_bound(index_segment);
return it;
}
@ -1611,9 +1616,6 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
while ( LLUrlRegistry::instance().findUrl(text, match,
boost::bind(&LLTextBase::replaceUrlLabel, this, _1, _2)) )
{
LLTextUtil::processUrlMatch(&match,this);
start = match.getStart();
end = match.getEnd()+1;
@ -1638,6 +1640,10 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
std::string subtext=text.substr(0,start);
appendAndHighlightText(subtext, part, style_params);
}
// inserts an avatar icon preceding the Url if appropriate
LLTextUtil::processUrlMatch(&match,this);
// output the styled Url (unless we've been asked to suppress hyperlinking)
if (match.isLinkDisabled())
{
@ -1645,7 +1651,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
}
else
{
appendAndHighlightText(match.getLabel(), part, link_params);
appendAndHighlightText(match.getLabel(), part, link_params, match.underlineOnHoverOnly());
// set the tooltip for the Url label
if (! match.getTooltip().empty())
@ -1728,7 +1734,7 @@ void LLTextBase::appendWidget(const LLInlineViewSegment::Params& params, const s
insertStringNoUndo(getLength(), widget_wide_text, &segments);
}
void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params)
void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only)
{
// Save old state
S32 selection_start = mSelectionStart;
@ -1759,7 +1765,17 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig
S32 cur_length = getLength();
LLStyleConstSP sp(new LLStyle(highlight_params));
LLTextSegmentPtr segmentp = new LLNormalTextSegment(sp, cur_length, cur_length + wide_text.size(), *this);
LLTextSegmentPtr segmentp;
if(underline_on_hover_only)
{
highlight_params.font.style("NORMAL");
LLStyleConstSP normal_sp(new LLStyle(highlight_params));
segmentp = new LLOnHoverChangeableTextSegment(sp, normal_sp, cur_length, cur_length + wide_text.size(), *this);
}
else
{
segmentp = new LLNormalTextSegment(sp, cur_length, cur_length + wide_text.size(), *this);
}
segment_vec_t segments;
segments.push_back(segmentp);
insertStringNoUndo(cur_length, wide_text, &segments);
@ -1774,7 +1790,17 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig
S32 segment_start = old_length;
S32 segment_end = old_length + wide_text.size();
LLStyleConstSP sp(new LLStyle(style_params));
if (underline_on_hover_only)
{
LLStyle::Params normal_style_params(style_params);
normal_style_params.font.style("NORMAL");
LLStyleConstSP normal_sp(new LLStyle(normal_style_params));
segments.push_back(new LLOnHoverChangeableTextSegment(sp, normal_sp, segment_start, segment_end, *this ));
}
else
{
segments.push_back(new LLNormalTextSegment(sp, segment_start, segment_end, *this ));
}
insertStringNoUndo(getLength(), wide_text, &segments);
}
@ -1798,7 +1824,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig
}
}
void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params)
void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only)
{
if (new_text.empty()) return;
@ -1810,7 +1836,7 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlig
if(pos!=start)
{
std::string str = std::string(new_text,start,pos-start);
appendAndHighlightTextImpl(str,highlight_part, style_params);
appendAndHighlightTextImpl(str,highlight_part, style_params, underline_on_hover_only);
}
appendLineBreakSegment(style_params);
start = pos+1;
@ -1818,7 +1844,7 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlig
}
std::string str = std::string(new_text,start,new_text.length()-start);
appendAndHighlightTextImpl(str,highlight_part, style_params);
appendAndHighlightTextImpl(str,highlight_part, style_params, underline_on_hover_only);
}
@ -2272,6 +2298,7 @@ void LLTextBase::updateRects()
// allow horizontal scrolling?
// if so, use entire width of text contents
// otherwise, stop at width of mVisibleTextRect
//FIXME: consider use of getWordWrap() instead
doc_rect.mRight = mScroller
? llmax(mVisibleTextRect.getWidth(), mTextBoundingRect.mRight)
: mVisibleTextRect.getWidth();
@ -2481,7 +2508,7 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
font->render(text, start,
rect,
LLColor4( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], 1.f ),
mStyle->getSelectedColor().get(),
LLFontGL::LEFT, mEditor.mVAlign,
LLFontGL::NORMAL,
LLFontGL::NO_SHADOW,
@ -2678,6 +2705,33 @@ void LLNormalTextSegment::dump() const
llendl;
}
//
// LLOnHoverChangeableTextSegment
//
LLOnHoverChangeableTextSegment::LLOnHoverChangeableTextSegment( LLStyleConstSP style, LLStyleConstSP normal_style, S32 start, S32 end, LLTextBase& editor ):
LLNormalTextSegment(normal_style, start, end, editor),
mHoveredStyle(style),
mNormalStyle(normal_style){}
/*virtual*/
F32 LLOnHoverChangeableTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)
{
F32 result = LLNormalTextSegment::draw(start, end, selection_start, selection_end, draw_rect);
if (end == mEnd - mStart)
{
mStyle = mNormalStyle;
}
return result;
}
/*virtual*/
BOOL LLOnHoverChangeableTextSegment::handleHover(S32 x, S32 y, MASK mask)
{
mStyle = mHoveredStyle;
return LLNormalTextSegment::handleHover(x, y, mask);
}
//
// LLInlineViewSegment

View File

@ -139,10 +139,25 @@ protected:
boost::signals2::connection mImageLoadedConnection;
};
// Text segment that changes it's style depending of mouse pointer position ( is it inside or outside segment)
class LLOnHoverChangeableTextSegment : public LLNormalTextSegment
{
public:
LLOnHoverChangeableTextSegment( LLStyleConstSP style, LLStyleConstSP normal_style, S32 start, S32 end, LLTextBase& editor );
/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
protected:
// Style used for text when mouse pointer is over segment
LLStyleConstSP mHoveredStyle;
// Style used for text when mouse pointer is outside segment
LLStyleConstSP mNormalStyle;
};
class LLIndexSegment : public LLTextSegment
{
public:
LLIndexSegment(S32 pos) : LLTextSegment(pos, pos) {}
LLIndexSegment() : LLTextSegment(0, 0) {}
};
class LLInlineViewSegment : public LLTextSegment
@ -235,7 +250,9 @@ public:
text_readonly_color,
bg_readonly_color,
bg_writeable_color,
bg_focus_color;
bg_focus_color,
text_selected_color,
bg_selected_color;
Optional<bool> bg_visible,
border_visible,
@ -245,7 +262,7 @@ public:
plain_text,
wrap,
use_ellipses,
allow_html,
parse_urls,
parse_highlights,
clip_partial;
@ -435,7 +452,7 @@ protected:
S32 insertStringNoUndo(S32 pos, const LLWString &wstr, segment_vec_t* segments = NULL); // returns num of chars actually inserted
S32 removeStringNoUndo(S32 pos, S32 length);
S32 overwriteCharNoUndo(S32 pos, llwchar wc);
void appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& stylep);
void appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& stylep, bool underline_on_hover_only = false);
// manage segments
@ -478,7 +495,7 @@ protected:
void replaceUrlLabel(const std::string &url, const std::string &label);
void appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params = LLStyle::Params());
void appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params);
void appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only = false);
protected:
@ -501,6 +518,8 @@ protected:
LLUIColor mWriteableBgColor;
LLUIColor mReadOnlyBgColor;
LLUIColor mFocusBgColor;
LLUIColor mTextSelectedColor;
LLUIColor mSelectedBGColor;
// cursor
S32 mCursorPos; // I-beam is just after the mCursorPos-th character.

View File

@ -113,6 +113,17 @@ BOOL LLTextBox::handleHover(S32 x, S32 y, MASK mask)
return handled;
}
void LLTextBox::setEnabled(BOOL enabled)
{
// just treat enabled as read-only flag
bool read_only = !enabled;
if (read_only != mReadOnly)
{
LLTextBase::setReadOnly(read_only);
updateSegments();
}
}
void LLTextBox::setText(const LLStringExplicit& text , const LLStyle::Params& input_params )
{
// does string argument insertion

View File

@ -52,6 +52,8 @@ public:
/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
/*virtual*/ void setEnabled(BOOL enabled);
/*virtual*/ void setText( const LLStringExplicit& text, const LLStyle::Params& input_params = LLStyle::Params() );
void setRightAlign() { mHAlign = LLFontGL::RIGHT; }

View File

@ -283,6 +283,9 @@ void LLTextEditor::initFromParams( const LLTextEditor::Params& p)
{
LLTextBase::initFromParams(p);
// HACK: text editors always need to be enabled so that we can scroll
LLView::setEnabled(true);
if (p.commit_on_focus_lost.isProvided())
{
mCommitOnFocusLost = p.commit_on_focus_lost;
@ -452,8 +455,13 @@ S32 LLTextEditor::nextWordPos(S32 cursorPos) const
const LLTextSegmentPtr LLTextEditor::getPreviousSegment() const
{
static LLPointer<LLIndexSegment> index_segment = new LLIndexSegment;
index_segment->setStart(mCursorPos);
index_segment->setEnd(mCursorPos);
// find segment index at character to left of cursor (or rightmost edge of selection)
segment_set_t::const_iterator it = mSegments.lower_bound(new LLIndexSegment(mCursorPos));
segment_set_t::const_iterator it = mSegments.lower_bound(index_segment);
if (it != mSegments.end())
{

View File

@ -44,6 +44,7 @@ namespace LLTextValidate
declare("alpha_num_space", validateAlphaNumSpace);
declare("ascii_printable_no_pipe", validateASCIIPrintableNoPipe);
declare("ascii_printable_no_space", validateASCIIPrintableNoSpace);
declare("ascii_with_newline", validateASCIIWithNewLine);
}
// Limits what characters can be used to [1234567890.-] with [-] only valid in the first position.
@ -293,4 +294,21 @@ namespace LLTextValidate
}
return rv;
}
// Used for multiline text stored on the server.
// Example is landmark description in Places SP.
bool validateASCIIWithNewLine(const LLWString &str)
{
bool rv = TRUE;
S32 len = str.length();
while(len--)
{
if (str[len] < 0x20 && str[len] != 0xA || str[len] > 0x7f)
{
rv = FALSE;
break;
}
}
return rv;
}
}

View File

@ -51,6 +51,7 @@ namespace LLTextValidate
bool validateASCIIPrintableNoPipe(const LLWString &str);
bool validateASCIIPrintableNoSpace(const LLWString &str);
bool validateASCII(const LLWString &str);
bool validateASCIIWithNewLine(const LLWString &str);
}

View File

@ -180,7 +180,7 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p)
params.font = p.font;
params.use_ellipses = true;
params.wrap = p.wrap;
params.allow_html = false; // disallow hyperlinks in tooltips, as they want to spawn their own explanatory tooltips
params.parse_urls = false; // disallow hyperlinks in tooltips, as they want to spawn their own explanatory tooltips
mTextBox = LLUICtrlFactory::create<LLTextBox> (params);
addChild(mTextBox);

View File

@ -460,7 +460,7 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border
gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect);
}
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect, const LLRectf& scale_rect)
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_outer_rect, const LLRectf& center_rect)
{
stop_glerror();
@ -470,36 +470,53 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
return;
}
// add in offset of current image to current ui translation
const LLVector3 ui_scale = gGL.getUIScale();
const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
F32 uv_width = uv_outer_rect.getWidth();
F32 uv_height = uv_outer_rect.getHeight();
// shrink scaling region to be proportional to clipped image region
LLRectf scale_rect_uv(
uv_rect.mLeft + (scale_rect.mLeft * uv_rect.getWidth()),
uv_rect.mBottom + (scale_rect.mTop * uv_rect.getHeight()),
uv_rect.mLeft + (scale_rect.mRight * uv_rect.getWidth()),
uv_rect.mBottom + (scale_rect.mBottom * uv_rect.getHeight()));
LLRectf uv_center_rect(
uv_outer_rect.mLeft + (center_rect.mLeft * uv_width),
uv_outer_rect.mBottom + (center_rect.mTop * uv_height),
uv_outer_rect.mLeft + (center_rect.mRight * uv_width),
uv_outer_rect.mBottom + (center_rect.mBottom * uv_height));
S32 image_natural_width = llround((F32)image->getWidth(0) * uv_rect.getWidth());
S32 image_natural_height = llround((F32)image->getHeight(0) * uv_rect.getHeight());
F32 image_width = image->getWidth(0);
F32 image_height = image->getHeight(0);
LLRect draw_rect(0, height, width, 0);
LLRect draw_scale_rect(llround(scale_rect_uv.mLeft * (F32)image->getWidth(0)),
llround(scale_rect_uv.mTop * (F32)image->getHeight(0)),
llround(scale_rect_uv.mRight * (F32)image->getWidth(0)),
llround(scale_rect_uv.mBottom * (F32)image->getHeight(0)));
// scale fixed region of image to drawn region
draw_scale_rect.mRight += width - image_natural_width;
draw_scale_rect.mTop += height - image_natural_height;
S32 image_natural_width = llround(image_width * uv_width);
S32 image_natural_height = llround(image_height * uv_height);
S32 border_shrink_width = llmax(0, draw_scale_rect.mLeft - draw_scale_rect.mRight);
S32 border_shrink_height = llmax(0, draw_scale_rect.mBottom - draw_scale_rect.mTop);
LLRectf draw_center_rect( uv_center_rect.mLeft * image_width,
uv_center_rect.mTop * image_height,
uv_center_rect.mRight * image_width,
uv_center_rect.mBottom * image_height);
F32 shrink_width_ratio = scale_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - scale_rect.getWidth()));
F32 shrink_height_ratio = scale_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - scale_rect.getHeight()));
{ // scale fixed region of image to drawn region
draw_center_rect.mRight += width - image_natural_width;
draw_center_rect.mTop += height - image_natural_height;
F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio);
draw_scale_rect.mLeft = llround((F32)draw_scale_rect.mLeft * shrink_scale);
draw_scale_rect.mTop = llround(lerp((F32)height, (F32)draw_scale_rect.mTop, shrink_scale));
draw_scale_rect.mRight = llround(lerp((F32)width, (F32)draw_scale_rect.mRight, shrink_scale));
draw_scale_rect.mBottom = llround((F32)draw_scale_rect.mBottom * shrink_scale);
F32 border_shrink_width = llmax(0.f, draw_center_rect.mLeft - draw_center_rect.mRight);
F32 border_shrink_height = llmax(0.f, draw_center_rect.mBottom - draw_center_rect.mTop);
F32 shrink_width_ratio = center_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - center_rect.getWidth()));
F32 shrink_height_ratio = center_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - center_rect.getHeight()));
F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio);
draw_center_rect.mLeft = llround(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * shrink_scale * ui_scale.mV[VX]);
draw_center_rect.mTop = llround(ui_translation.mV[VY] + lerp((F32)height, (F32)draw_center_rect.mTop, shrink_scale) * ui_scale.mV[VY]);
draw_center_rect.mRight = llround(ui_translation.mV[VX] + lerp((F32)width, (F32)draw_center_rect.mRight, shrink_scale) * ui_scale.mV[VX]);
draw_center_rect.mBottom = llround(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * shrink_scale * ui_scale.mV[VY]);
}
LLRectf draw_outer_rect(ui_translation.mV[VX],
ui_translation.mV[VY] + height * ui_scale.mV[VY],
ui_translation.mV[VX] + width * ui_scale.mV[VX],
ui_translation.mV[VY]);
LLGLSUIDefault gls_ui;
@ -509,136 +526,174 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA);
}
gGL.pushUIMatrix();
gGL.getTexUnit(0)->bind(image);
gGL.color4fv(color.mV);
const S32 NUM_VERTICES = 9 * 4; // 9 quads
LLVector2 uv[NUM_VERTICES];
LLVector3 pos[NUM_VERTICES];
S32 index = 0;
gGL.begin(LLRender::QUADS);
{
gGL.translateUI((F32)x, (F32)y, 0.f);
// draw bottom left
uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mBottom);
pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f);
index++;
gGL.getTexUnit(0)->bind(image);
uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
index++;
gGL.color4fv(color.mV);
gGL.begin(LLRender::QUADS);
{
// draw bottom left
gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
gGL.vertex2i(0, 0);
uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
index++;
gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mBottom);
gGL.vertex2i(draw_scale_rect.mLeft, 0);
uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
index++;
gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom);
gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom);
// draw bottom middle
uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
index++;
gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mBottom);
gGL.vertex2i(0, draw_scale_rect.mBottom);
uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
index++;
// draw bottom middle
gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mBottom);
gGL.vertex2i(draw_scale_rect.mLeft, 0);
uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
index++;
gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mBottom);
gGL.vertex2i(draw_scale_rect.mRight, 0);
uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
index++;
gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom);
gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom);
// draw bottom right
uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
index++;
gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom);
gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom);
uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom);
pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f);
index++;
// draw bottom right
gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mBottom);
gGL.vertex2i(draw_scale_rect.mRight, 0);
uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
index++;
gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
gGL.vertex2i(width, 0);
uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
index++;
gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mBottom);
gGL.vertex2i(width, draw_scale_rect.mBottom);
// draw left
uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
index++;
gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom);
gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom);
uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
index++;
// draw left
gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mBottom);
gGL.vertex2i(0, draw_scale_rect.mBottom);
uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
index++;
gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom);
gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom);
uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
index++;
gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop);
gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop);
// draw middle
uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
index++;
gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mTop);
gGL.vertex2i(0, draw_scale_rect.mTop);
uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
index++;
// draw middle
gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom);
gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom);
uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
index++;
gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom);
gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom);
uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
index++;
gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop);
gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop);
// draw right
uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
index++;
gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop);
gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop);
uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
index++;
// draw right
gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom);
gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom);
uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
index++;
gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mBottom);
gGL.vertex2i(width, draw_scale_rect.mBottom);
uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
index++;
gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mTop);
gGL.vertex2i(width, draw_scale_rect.mTop);
// draw top left
uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
index++;
gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop);
gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop);
uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
index++;
// draw top left
gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mTop);
gGL.vertex2i(0, draw_scale_rect.mTop);
uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
index++;
gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop);
gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop);
uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop);
pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f);
index++;
gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mTop);
gGL.vertex2i(draw_scale_rect.mLeft, height);
// draw top middle
uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
index++;
gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
gGL.vertex2i(0, height);
uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
index++;
// draw top middle
gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop);
gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop);
uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
index++;
gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop);
gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop);
uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
index++;
gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mTop);
gGL.vertex2i(draw_scale_rect.mRight, height);
// draw top right
uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
index++;
gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mTop);
gGL.vertex2i(draw_scale_rect.mLeft, height);
uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
index++;
// draw top right
gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop);
gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop);
uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop);
pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f);
index++;
gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mTop);
gGL.vertex2i(width, draw_scale_rect.mTop);
uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
index++;
gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
gGL.vertex2i(width, height);
gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mTop);
gGL.vertex2i(draw_scale_rect.mRight, height);
}
gGL.end();
gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
}
gGL.popUIMatrix();
gGL.end();
if (solid_color)
{
@ -668,25 +723,40 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
if (degrees == 0.f)
{
gGL.pushUIMatrix();
gGL.translateUI((F32)x, (F32)y, 0.f);
const S32 NUM_VERTICES = 4; // 9 quads
LLVector2 uv[NUM_VERTICES];
LLVector3 pos[NUM_VERTICES];
gGL.begin(LLRender::QUADS);
{
gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
gGL.vertex2i(width, height );
LLVector3 ui_scale = gGL.getUIScale();
LLVector3 ui_translation = gGL.getUITranslation();
ui_translation.mV[VX] += x;
ui_translation.mV[VY] += y;
ui_translation.scaleVec(ui_scale);
S32 index = 0;
S32 scaled_width = llround(width * ui_scale.mV[VX]);
S32 scaled_height = llround(height * ui_scale.mV[VY]);
gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
gGL.vertex2i(0, height );
uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f);
index++;
gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
gGL.vertex2i(0, 0);
uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f);
index++;
gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
gGL.vertex2i(width, 0);
uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f);
index++;
uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f);
index++;
gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
}
gGL.end();
gGL.popUIMatrix();
}
else
{
@ -755,25 +825,6 @@ void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LL
LLUI::setLineWidth(1.f);
}
void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom)
{
gGL.color4fv( LLColor4::white.mV );
glLogicOp( GL_XOR );
stop_glerror();
gGL.begin(LLRender::QUADS);
gGL.vertex2i(left, top);
gGL.vertex2i(left, bottom);
gGL.vertex2i(right, bottom);
gGL.vertex2i(right, top);
gGL.end();
glLogicOp( GL_COPY );
stop_glerror();
}
void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle)
{
if (end_angle < start_angle)
@ -1007,42 +1058,6 @@ void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians,
gGL.end();
}
// Draws spokes around a circle.
void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color)
{
const F32 DELTA = F_TWO_PI / count;
const F32 HALF_DELTA = DELTA * 0.5f;
const F32 SIN_DELTA = sin( DELTA );
const F32 COS_DELTA = cos( DELTA );
F32 x1 = outer_radius * cos( HALF_DELTA );
F32 y1 = outer_radius * sin( HALF_DELTA );
F32 x2 = inner_radius * cos( HALF_DELTA );
F32 y2 = inner_radius * sin( HALF_DELTA );
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.begin( LLRender::LINES );
{
while( count-- )
{
gGL.color4fv(outer_color.mV);
gGL.vertex2f( x1, y1 );
gGL.color4fv(inner_color.mV);
gGL.vertex2f( x2, y2 );
F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
y1 = x1 * SIN_DELTA + y1 * COS_DELTA;
x1 = x1_new;
F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
y2 = x2 * SIN_DELTA + y2 * COS_DELTA;
x2 = x2_new;
}
}
gGL.end();
}
void gl_rect_2d_simple_tex( S32 width, S32 height )
{
gGL.begin( LLRender::QUADS );
@ -1230,6 +1245,7 @@ void gl_segmented_rect_2d_tex(const S32 left,
gGL.popUIMatrix();
}
//FIXME: rewrite to use scissor?
void gl_segmented_rect_2d_fragment_tex(const S32 left,
const S32 top,
const S32 right,

View File

@ -90,7 +90,6 @@ void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor
void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac);
void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color);
void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
@ -99,7 +98,6 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom);
void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f );
void gl_rect_2d_simple_tex( S32 width, S32 height );

View File

@ -95,6 +95,7 @@ LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel)
: LLView(p),
mTentative(FALSE),
mIsChrome(FALSE),
mTabStop(FALSE),
mViewModel(viewmodel),
mControlVariable(NULL),
mEnabledControlVariable(NULL),

View File

@ -141,8 +141,6 @@ public:
// LLView interface
/*virtual*/ BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
/*virtual*/ BOOL isCtrl() const;
/*virtual*/ void setTentative(BOOL b);
/*virtual*/ BOOL getTentative() const;
/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL canFocusChildren() const;
@ -174,6 +172,8 @@ public:
void setMakeVisibleControlVariable(LLControlVariable* control);
void setMakeInvisibleControlVariable(LLControlVariable* control);
virtual void setTentative(BOOL b);
virtual BOOL getTentative() const;
virtual void setValue(const LLSD& value);
virtual LLSD getValue() const;
/// When two widgets are displaying the same data (e.g. during a skin

View File

@ -357,6 +357,12 @@ std::string LLUrlEntryAgent::getTooltip(const std::string &string) const
return LLTrans::getString("TooltipAgentUrl");
}
bool LLUrlEntryAgent::underlineOnHoverOnly(const std::string &string) const
{
std::string url = getUrl(string);
return LLStringUtil::endsWith(url, "/about") || LLStringUtil::endsWith(url, "/inspect");
}
std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
{
if (!gCacheName)
@ -724,6 +730,19 @@ std::string LLUrlEntrySLLabel::getTooltip(const std::string &string) const
return LLUrlEntryBase::getTooltip(string);
}
bool LLUrlEntrySLLabel::underlineOnHoverOnly(const std::string &string) const
{
std::string url = getUrl(string);
LLUrlMatch match;
if (LLUrlRegistry::instance().findUrl(url, match))
{
return match.underlineOnHoverOnly();
}
// unrecognized URL? should not happen
return LLUrlEntryBase::underlineOnHoverOnly(string);
}
//
// LLUrlEntryWorldMap Describes secondlife:///<location> URLs
//

View File

@ -88,6 +88,9 @@ public:
/// is this a match for a URL that should not be hyperlinked?
bool isLinkDisabled() const { return mDisabledLink; }
/// Should this link text be underlined only when mouse is hovered over it?
virtual bool underlineOnHoverOnly(const std::string &string) const { return false; }
virtual LLUUID getID(const std::string &string) const { return LLUUID::null; }
protected:
@ -167,6 +170,7 @@ public:
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
/*virtual*/ std::string getTooltip(const std::string &string) const;
/*virtual*/ LLUUID getID(const std::string &string) const;
/*virtual*/ bool underlineOnHoverOnly(const std::string &string) const;
private:
void onAgentNameReceived(const LLUUID& id, const std::string& first,
const std::string& last, BOOL is_group);
@ -269,6 +273,7 @@ public:
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
/*virtual*/ std::string getUrl(const std::string &string) const;
/*virtual*/ std::string getTooltip(const std::string &string) const;
/*virtual*/ bool underlineOnHoverOnly(const std::string &string) const;
};
///

View File

@ -37,7 +37,8 @@ LLUrlMatch::LLUrlMatch() :
mIcon(""),
mMenuName(""),
mLocation(""),
mDisabledLink(false)
mDisabledLink(false),
mUnderlineOnHoverOnly(false)
{
}
@ -45,7 +46,7 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url,
const std::string &label, const std::string &tooltip,
const std::string &icon, const LLUIColor& color,
const std::string &menu, const std::string &location,
bool disabled_link, const LLUUID& id)
bool disabled_link, const LLUUID& id, bool underline_on_hover_only)
{
mStart = start;
mEnd = end;
@ -58,4 +59,5 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url,
mLocation = location;
mDisabledLink = disabled_link;
mID = id;
mUnderlineOnHoverOnly = underline_on_hover_only;
}

View File

@ -80,12 +80,15 @@ public:
/// is this a match for a URL that should not be hyperlinked?
bool isLinkDisabled() const { return mDisabledLink; }
/// Should this link text be underlined only when mouse is hovered over it?
bool underlineOnHoverOnly() const { return mUnderlineOnHoverOnly; }
/// Change the contents of this match object (used by LLUrlRegistry)
void setValues(U32 start, U32 end, const std::string &url, const std::string &label,
const std::string &tooltip, const std::string &icon,
const LLUIColor& color, const std::string &menu,
const std::string &location, bool disabled_link
, const LLUUID& id );
, const LLUUID& id, bool underline_on_hover_only = false );
const LLUUID& getID() const { return mID;}
@ -102,6 +105,7 @@ private:
LLUUID mID;
LLUIColor mColor;
bool mDisabledLink;
bool mUnderlineOnHoverOnly;
};
#endif

View File

@ -178,7 +178,8 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
match_entry->getMenuName(),
match_entry->getLocation(url),
match_entry->isLinkDisabled(),
match_entry->getID(url));
match_entry->getID(url),
match_entry->underlineOnHoverOnly(url));
return true;
}
@ -213,7 +214,8 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr
match.getMenuName(),
match.getLocation(),
match.isLinkDisabled(),
match.getID());
match.getID(),
match.underlineOnHoverOnly());
return true;
}
return false;

View File

@ -397,28 +397,40 @@ bool LLCompareByTabOrder::operator() (const LLView* const a, const LLView* const
return (a_score == b_score) ? a < b : a_score < b_score;
}
bool LLView::trueToRoot(const boost::function<bool (const LLView*)>& predicate) const
{
const LLView* cur_view = this;
while(cur_view)
{
if(!predicate(cur_view))
{
return false;
}
cur_view = cur_view->getParent();
}
return true;
}
BOOL LLView::isInVisibleChain() const
{
return trueToRoot(&LLView::getVisible);
BOOL visible = TRUE;
const LLView* viewp = this;
while(viewp)
{
if (!viewp->getVisible())
{
visible = FALSE;
break;
}
viewp = viewp->getParent();
}
return visible;
}
BOOL LLView::isInEnabledChain() const
{
return trueToRoot(&LLView::getEnabled);
BOOL enabled = TRUE;
const LLView* viewp = this;
while(viewp)
{
if (!viewp->getEnabled())
{
enabled = FALSE;
break;
}
viewp = viewp->getParent();
}
return enabled;
}
// virtual
@ -427,17 +439,6 @@ BOOL LLView::canFocusChildren() const
return TRUE;
}
//virtual
void LLView::setTentative(BOOL b)
{
}
//virtual
BOOL LLView::getTentative() const
{
return FALSE;
}
//virtual
void LLView::setEnabled(BOOL enabled)
{
@ -2778,6 +2779,19 @@ LLView::tree_post_iterator_t LLView::endTreeDFSPost()
return tree_post_iterator_t();
}
LLView::bfs_tree_iterator_t LLView::beginTreeBFS()
{
return bfs_tree_iterator_t(this,
boost::bind(boost::mem_fn(&LLView::beginChild), _1),
boost::bind(boost::mem_fn(&LLView::endChild), _1));
}
LLView::bfs_tree_iterator_t LLView::endTreeBFS()
{
// an empty iterator is an "end" iterator
return bfs_tree_iterator_t();
}
LLView::root_to_view_iterator_t LLView::beginRootToView()
{

View File

@ -267,7 +267,6 @@ public:
S32 getDefaultTabGroup() const { return mDefaultTabGroup; }
S32 getLastTabGroup() { return mLastTabGroup; }
bool trueToRoot(const boost::function<bool (const LLView*)>& predicate) const;
BOOL isInVisibleChain() const;
BOOL isInEnabledChain() const;
@ -283,8 +282,6 @@ public:
// children, etc.
virtual void deleteAllChildren();
virtual void setTentative(BOOL b);
virtual BOOL getTentative() const;
void setAllChildrenEnabled(BOOL b);
virtual void setVisible(BOOL visible);
@ -351,6 +348,10 @@ public:
tree_post_iterator_t beginTreeDFSPost();
tree_post_iterator_t endTreeDFSPost();
typedef LLTreeBFSIter<LLView, child_list_const_iter_t> bfs_tree_iterator_t;
bfs_tree_iterator_t beginTreeBFS();
bfs_tree_iterator_t endTreeBFS();
typedef LLTreeDownIter<LLView> root_to_view_iterator_t;
root_to_view_iterator_t beginRootToView();

View File

@ -337,6 +337,13 @@ std::string LLKeyboard::stringFromKey(KEY key)
buffer[1] = '\0';
res = std::string(buffer);
}
LLKeyStringTranslatorFunc *trans = gKeyboard->mStringTranslator;
if (trans != NULL)
{
res = trans(res.c_str());
}
return res;
}

View File

@ -97,11 +97,12 @@ public:
return findString(result, xml_desc, empty);
}
static std::string getKeyboardString(const char* keystring)
{
// These map directly - no need to specialize
return getString( ll_safe_string(keystring) );
}
static std::string getKeyboardString(const char* keystring)
{
std::string key_str(keystring);
std::string trans_str;
return findString(trans_str, key_str) ? trans_str : key_str;
}
// get the default args
static const LLStringUtil::format_map_t& getDefaultArgs()

View File

@ -190,7 +190,6 @@ set(viewer_SOURCE_FILES
llfloaternamedesc.cpp
llfloaternotificationsconsole.cpp
llfloateropenobject.cpp
llfloaterparcel.cpp
llfloaterpay.cpp
llfloaterperms.cpp
llfloaterpostcard.cpp
@ -212,7 +211,6 @@ set(viewer_SOURCE_FILES
llfloatertopobjects.cpp
llfloatertos.cpp
llfloateruipreview.cpp
llfloaterurldisplay.cpp
llfloaterurlentry.cpp
llfloatervoicedevicesettings.cpp
llfloatervoiceeffect.cpp
@ -349,7 +347,6 @@ set(viewer_SOURCE_FILES
llpanelpermissions.cpp
llpanelpick.cpp
llpanelpicks.cpp
llpanelplace.cpp
llpanelplaceinfo.cpp
llpanelplaceprofile.cpp
llpanelplaces.cpp
@ -552,6 +549,7 @@ set(viewer_SOURCE_FILES
llwearablelist.cpp
llwearabletype.cpp
llweb.cpp
llwebsharing.cpp
llwind.cpp
llwlanimator.cpp
llwldaycycle.cpp
@ -716,7 +714,6 @@ set(viewer_HEADER_FILES
llfloaternamedesc.h
llfloaternotificationsconsole.h
llfloateropenobject.h
llfloaterparcel.h
llfloaterpay.h
llfloaterperms.h
llfloaterpostcard.h
@ -738,7 +735,6 @@ set(viewer_HEADER_FILES
llfloatertopobjects.h
llfloatertos.h
llfloateruipreview.h
llfloaterurldisplay.h
llfloaterurlentry.h
llfloatervoicedevicesettings.h
llfloatervoiceeffect.h
@ -871,7 +867,6 @@ set(viewer_HEADER_FILES
llpanelpermissions.h
llpanelpick.h
llpanelpicks.h
llpanelplace.h
llpanelplaceinfo.h
llpanelplaceprofile.h
llpanelplaces.h
@ -1076,6 +1071,7 @@ set(viewer_HEADER_FILES
llwearablelist.h
llwearabletype.h
llweb.h
llwebsharing.h
llwind.h
llwlanimator.h
llwldaycycle.h
@ -1394,10 +1390,6 @@ add_executable(${VIEWER_BINARY_NAME}
${viewer_SOURCE_FILES}
)
if (LLKDU_LIBRARY)
add_dependencies(${VIEWER_BINARY_NAME} ${LLKDU_LIBRARY})
endif (LLKDU_LIBRARY)
# add package files
file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py)
@ -1555,11 +1547,6 @@ if (WINDOWS)
add_dependencies(${VIEWER_BINARY_NAME} stage_third_party_libs llcommon copy_w_viewer_manifest)
if(LLKDU_LIBRARY)
# kdu may not exist!
add_dependencies(copy_w_viewer_manifest llkdu)
endif(LLKDU_LIBRARY)
if (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts)
add_dependencies(${VIEWER_BINARY_NAME} copy_win_scripts)
endif (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts)

View File

@ -7,8 +7,8 @@ install(DIRECTORY skins app_settings linux_tools
PATTERN ".svn" EXCLUDE
)
find_file(IS_ARTWORK_PRESENT NAMES avatar_lad.xml
PATHS ${VIEWER_DIR}/newview/character)
find_file(IS_ARTWORK_PRESENT NAMES have_artwork_bundle.marker
PATHS ${VIEWER_DIR}/newview/res)
if (IS_ARTWORK_PRESENT)
install(DIRECTORY res res-sdl character

View File

@ -12,8 +12,6 @@
<RenderFlexTimeFactor value="1"/>
<!--256... but they don't use this-->
<RenderGlowResolutionPow value="9"/>
<!--Sun/Moon only-->
<RenderLightingDetail value="1"/>
<!--Low number-->
<RenderMaxPartCount value="4096"/>
<!--bump okay-->
@ -31,9 +29,14 @@
<!--Default for now-->
<RenderVolumeLODFactor value="1.125"/>
<!--NO SHADERS-->
<RenderWaterReflections value="FALSE"/>
<!--NO SHADERS-->
<VertexShaderEnable value="TRUE"/>
<!--NO SHADERS-->
<WindLightUseAtmosShaders value="TRUE"/>
<!--Deferred Shading-->
<RenderDeferred value="FALSE"/>
<!--SSAO Disabled-->
<RenderDeferredSSAO value="FALSE"/>
<!--Sun Shadows-->
<RenderShadowDetail value="0"/>
</settings>

View File

@ -14,8 +14,6 @@
<RenderFlexTimeFactor value="0.5"/>
<!--256... but they don't use this-->
<RenderGlowResolutionPow value="8"/>
<!--Sun/Moon only-->
<RenderLightingDetail value="0"/>
<!--Low number-->
<RenderMaxPartCount value="1024"/>
<!--bump okay-->
@ -33,9 +31,14 @@
<!--Default for now-->
<RenderVolumeLODFactor value="1.125"/>
<!--NO SHADERS-->
<RenderWaterReflections value="FALSE"/>
<!--NO SHADERS-->
<VertexShaderEnable value="FALSE"/>
<!--NO SHADERS-->
<WindLightUseAtmosShaders value="FALSE"/>
<!--No Deferred Shading-->
<RenderDeferred value="FALSE"/>
<!--SSAO Disabled-->
<RenderDeferredSSAO value="FALSE"/>
<!--No Shadows-->
<RenderShadowDetail value="0"/>
</settings>

View File

@ -12,8 +12,6 @@
<RenderFlexTimeFactor value="1"/>
<!--256... but they don't use this-->
<RenderGlowResolutionPow value="8"/>
<!--Sun/Moon only-->
<RenderLightingDetail value="1"/>
<!--Low number-->
<RenderMaxPartCount value="2048"/>
<!--bump okay-->
@ -31,9 +29,14 @@
<!--Default for now-->
<RenderVolumeLODFactor value="1.125"/>
<!--NO SHADERS-->
<RenderWaterReflections value="FALSE"/>
<!--NO SHADERS-->
<VertexShaderEnable value="TRUE"/>
<!--NO SHADERS-->
<WindLightUseAtmosShaders value="FALSE"/>
<!--No Deferred Shading-->
<RenderDeferred value="FALSE"/>
<!--SSAO Disabled-->
<RenderDeferredSSAO value="FALSE"/>
<!--No Shadows-->
<RenderShadowDetail value="0"/>
</settings>

View File

@ -1741,6 +1741,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>DebugAvatarLocalTexLoadedTime</key>
<map>
<key>Comment</key>
<string>Display time for loading avatar local textures.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>DebugBeaconLineWidth</key>
<map>
<key>Comment</key>
@ -5373,17 +5384,6 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>MultipleAttachments</key>
<map>
<key>Comment</key>
<string>Allow multiple objects to be attached to a single attachment point.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>MuteAmbient</key>
<map>
<key>Comment</key>
@ -6748,7 +6748,7 @@
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>60</integer>
<integer>200</integer>
</map>
<key>RenderSSAOFactor</key>
<map>
@ -7123,6 +7123,64 @@
<real>0.01</real>
</map>
<key>RenderShadowBiasError</key>
<map>
<key>Comment</key>
<string>Error scale for shadow bias (based on altitude).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0</real>
</map>
<key>RenderShadowOffsetError</key>
<map>
<key>Comment</key>
<string>Error scale for shadow offset (based on altitude).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0</real>
</map>
<key>RenderSpotLightsInNondeferred</key>
<map>
<key>Comment</key>
<string>Whether to support projectors as spotlights when Lighting and Shadows is disabled</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>RenderSpotShadowBias</key>
<map>
<key>Comment</key>
<string>Bias value for shadows (prevent shadow acne).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.0</real>
</map>
<key>RenderSpotShadowOffset</key>
<map>
<key>Comment</key>
<string>Offset value for shadows (prevent shadow acne).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.04</real>
</map>
<key>RenderShadowResolutionScale</key>
<map>
<key>Comment</key>
@ -7135,8 +7193,6 @@
<real>1.0</real>
</map>
<key>RenderDeferredTreeShadowBias</key>
<map>
<key>Comment</key>
@ -7258,7 +7314,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>1</real>
<real>8</real>
</map>
<key>RenderDeferred</key>
@ -7273,18 +7329,6 @@
<integer>0</integer>
</map>
<key>RenderDeferredShadow</key>
<map>
<key>Comment</key>
<string>Enable shadows in deferred renderer.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>RenderDeferredGI</key>
<map>
<key>Comment</key>
@ -7297,18 +7341,6 @@
<integer>0</integer>
</map>
<key>RenderDeferredSunShadow</key>
<map>
<key>Comment</key>
<string>Generate shadows from the sun.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>RenderDeferredSun</key>
<map>
<key>Comment</key>
@ -7333,6 +7365,18 @@
<integer>1</integer>
</map>
<key>RenderDeferredSSAO</key>
<map>
<key>Comment</key>
<string>Execute screen space ambient occlusion shader in deferred renderer.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>RenderDeferredBlurLight</key>
<map>
<key>Comment</key>
@ -7583,10 +7627,10 @@
<key>Value</key>
<real>256.0</real>
</map>
<key>RenderFastAlpha</key>
<key>RenderAutoMaskAlphaNonDeferred</key>
<map>
<key>Comment</key>
<string>Use lossy alpha rendering optimization (opaque/nonexistent small alpha faces).</string>
<string>Use alpha masks where appropriate, in the non-deferred (non-'Lighting and Shadows') graphics mode</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@ -7594,6 +7638,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>RenderAutoMaskAlphaDeferred</key>
<map>
<key>Comment</key>
<string>Use alpha masks where appropriate, in the deferred ('Lighting and Shadows') graphics mode</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>RenderFastUI</key>
<map>
<key>Comment</key>
@ -7855,17 +7910,6 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>RenderLightingDetail</key>
<map>
<key>Comment</key>
<string>Amount of detail for lighting objects/avatars/terrain (0=sun/moon only, 1=enable local lights)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>RenderMaxPartCount</key>
<map>
<key>Comment</key>
@ -7965,6 +8009,18 @@
<key>Value</key>
<integer>2</integer>
</map>
<key>RenderShadowDetail</key>
<map>
<key>Comment</key>
<string>Detail of shadows.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>2</integer>
</map>
<key>RenderReflectionRes</key>
<map>
<key>Comment</key>
@ -8095,7 +8151,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
<integer>1</integer>
</map>
<key>RenderUIBuffer</key>
<map>
@ -8251,17 +8307,6 @@
<key>Value</key>
<integer>512</integer>
</map>
<key>RenderWaterReflections</key>
<map>
<key>Comment</key>
<string>Reflect the environment in the water.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>RotateRight</key>
<map>
<key>Comment</key>
@ -8284,17 +8329,6 @@
<key>Value</key>
<real>1.0</real>
</map>
<key>RunMultipleThreads</key>
<map>
<key>Comment</key>
<string>If TRUE keep background threads active during render</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>SafeMode</key>
<map>
<key>Comment</key>
@ -8601,7 +8635,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
<integer>1</integer>
</map>
<key>ShowBetaGrids</key>
<map>
@ -9461,6 +9495,28 @@
<key>Value</key>
<integer>75</integer>
</map>
<key>SnapshotSharingEnabled</key>
<map>
<key>Comment</key>
<string>Enable uploading of snapshots to a web service.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>SnapshotConfigURL</key>
<map>
<key>Comment</key>
<string>URL to fetch Snapshot Sharing configuration data from.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>http://photos.apps.staging.avatarsunited.com/viewer_config</string>
</map>
<key>SnapshotTextureLastResolution</key>
<map>
<key>Comment</key>

View File

@ -24,8 +24,6 @@ varying vec3 vary_fragcoord;
varying vec3 vary_position;
varying vec3 vary_light;
uniform float alpha_soften;
uniform mat4 inv_proj;
vec4 getPosition(vec2 pos_screen)
@ -57,15 +55,6 @@ void main()
color.rgb = scaleSoftClip(color.rgb);
if (samp_pos.z != 0.0 && gl_Color.a < 1.0)
{
float dist_factor = alpha_soften;
float a = gl_Color.a;
a *= a;
dist_factor *= 1.0/(1.0-a);
color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0);
}
//gl_FragColor = gl_Color;
gl_FragColor = color;
//gl_FragColor = vec4(1,0,1,1);

View File

@ -9,7 +9,7 @@ vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
void calcAtmospherics(vec3 inPositionEye);
float calcDirectionalLight(vec3 n, vec3 l);
float calcPointLight(vec3 v, vec3 n, vec4 lp, float la);
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity);
@ -41,23 +41,22 @@ void main()
calcAtmospherics(pos.xyz);
//vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.));
vec4 col;
col.a = gl_Color.a;
// Add windlight lights
col.rgb = atmosAmbient(vec3(0.));
col.rgb = scaleUpLight(col.rgb);
vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);
// Collect normal lights (need to be divided by two, as we later multiply by 2)
col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation);
col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation);
col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation);
col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation);
col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation);
col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation);
col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a);
col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a);
col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a);
col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a);
col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a);
col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a);
col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);
col.rgb = scaleDownLight(col.rgb);
// Add windlight lights
col.rgb += atmosAmbient(vec3(0.));
vary_light = gl_LightSource[0].position.xyz;
vary_ambient = col.rgb*gl_Color.rgb;

View File

@ -10,7 +10,7 @@ mat4 getSkinnedTransform();
void calcAtmospherics(vec3 inPositionEye);
float calcDirectionalLight(vec3 n, vec3 l);
float calcPointLight(vec3 v, vec3 n, vec4 lp, float la);
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity);
@ -47,23 +47,22 @@ void main()
calcAtmospherics(pos.xyz);
//vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.));
vec4 col;
col.a = gl_Color.a;
// Add windlight lights
col.rgb = atmosAmbient(vec3(0.));
col.rgb = scaleUpLight(col.rgb);
vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);
// Collect normal lights (need to be divided by two, as we later multiply by 2)
col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation);
col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation);
col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation);
col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation);
col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation);
col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation);
col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a);
col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a);
col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a);
col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a);
col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a);
col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a);
col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);
col.rgb = scaleDownLight(col.rgb);
// Add windlight lights
col.rgb += atmosAmbient(vec3(0.));
vary_ambient = col.rgb*gl_Color.rgb;
vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a)));

View File

@ -20,6 +20,7 @@ void main()
gl_FragData[0] = vec4(diff.rgb, 0.0);
gl_FragData[1] = vec4(0,0,0,0);
gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0);
vec3 nvn = normalize(vary_normal);
gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
}

View File

@ -10,7 +10,7 @@ uniform sampler2D diffuseMap;
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_FragColor = vec4(1,1,1,gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy).a);
gl_FragColor = vec4(1,1,1,1);
}

View File

@ -10,13 +10,11 @@
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
uniform sampler2DRect lightMap;
uniform sampler2DRect giLightMap;
uniform float dist_factor;
uniform float blur_size;
uniform vec2 delta;
uniform vec3 kern[32];
uniform int kern_length;
uniform vec3 kern[4];
uniform float kern_scale;
varying vec2 vary_fragcoord;
@ -39,7 +37,8 @@ vec4 getPosition(vec2 pos_screen)
void main()
{
vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0;
vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz;
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
vec3 pos = getPosition(vary_fragcoord.xy).xyz;
vec4 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rgba;
@ -50,7 +49,7 @@ void main()
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;
for (int i = 1; i < kern_length; i++)
for (int i = 1; i < 4; i++)
{
vec2 tc = vary_fragcoord.xy + kern[i].z*dlt;
vec3 samppos = getPosition(tc).xyz;
@ -61,12 +60,22 @@ void main()
defined_weight += kern[i].xy;
}
}
for (int i = 1; i < 4; i++)
{
vec2 tc = vary_fragcoord.xy - kern[i].z*dlt;
vec3 samppos = getPosition(tc).xyz;
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
if (d*d <= 0.003)
{
col += texture2DRect(lightMap, tc)*kern[i].xyxx;
defined_weight += kern[i].xy;
}
}
col /= defined_weight.xyxx;
gl_FragColor = col;
//gl_FragColor = ccol;
}

View File

@ -14,14 +14,16 @@ varying vec3 vary_mat2;
void main()
{
vec3 col = texture2D(diffuseMap, gl_TexCoord[0].xy).rgb;
vec3 col = gl_Color.rgb * texture2D(diffuseMap, gl_TexCoord[0].xy).rgb;
vec3 norm = texture2D(bumpMap, gl_TexCoord[0].xy).rgb * 2.0 - 1.0;
vec3 tnorm = vec3(dot(norm,vary_mat0),
dot(norm,vary_mat1),
dot(norm,vary_mat2));
dot(norm,vary_mat1),
dot(norm,vary_mat2));
gl_FragData[0] = vec4(gl_Color.rgb*col, 0.0);
gl_FragData[1] = vec4(col*gl_Color.a, gl_Color.a);
gl_FragData[2] = vec4(normalize(tnorm)*0.5+0.5, 0.0);
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(tnorm);
gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
}

View File

@ -11,8 +11,10 @@ varying vec3 vary_normal;
void main()
{
vec3 col = texture2D(diffuseMap, gl_TexCoord[0].xy).rgb;
gl_FragData[0] = vec4(gl_Color.rgb*col, 0.0);
gl_FragData[1] = vec4(col*(gl_Color.a*1.5), gl_Color.a);
gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0);
vec3 col = gl_Color.rgb * texture2D(diffuseMap, 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

@ -23,8 +23,6 @@ varying vec4 vary_position;
varying vec3 vary_normal;
varying vec3 vary_fragcoord;
uniform float alpha_soften;
uniform mat4 inv_proj;
vec4 getPosition(vec2 pos_screen)
@ -56,15 +54,6 @@ void main()
color.rgb = fullbrightScaleSoftClip(color.rgb);
if (samp_pos.z != 0.0 && color.a < 1.0)
{
float dist_factor = alpha_soften;
float a = color.a;
a *= a;
dist_factor *= 1.0/(1.0-a);
color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0);
}
//gl_FragColor = gl_Color;
gl_FragColor = color;
//gl_FragColor = vec4(1,0,1,1);

View File

@ -159,7 +159,8 @@ void main()
{
vec2 pos_screen = vary_fragcoord.xy;
vec4 pos = getPosition(pos_screen);
vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0;
vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
gl_FragData[0].xyz = giAmbient(pos, norm);
}

View File

@ -11,7 +11,8 @@ uniform sampler2D specularMap;
void main()
{
gl_FragData[0] = texture2D(diffuseMap, gl_TexCoord[0].xy);
vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy);
gl_FragData[0] = vec4(col.rgb, col.a <= 0.5 ? 0.0 : 0.005);
gl_FragData[1] = texture2D(specularMap, gl_TexCoord[0].xy);
gl_FragData[2] = vec4(texture2D(normalMap, gl_TexCoord[0].xy).xyz, 0.0);
}

View File

@ -53,7 +53,9 @@ void main()
discard;
}
vec3 norm = normalize(texture2DRect(normalMap, frag.xy).xyz*2.0-1.0);
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
norm = normalize(norm);
vec4 spec = texture2DRect(specularRect, frag.xy);
vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;
float noise = texture2D(noiseMap, frag.xy/128.0).b;

View File

@ -5,9 +5,10 @@
* $License$
*/
#version 120
//class 1 -- no shadows
#extension GL_ARB_texture_rectangle : enable
uniform sampler2DRect diffuseRect;
@ -26,12 +27,15 @@ uniform vec3 proj_n;
uniform float proj_focus; //distance from plane to begin blurring
uniform float proj_lod; //(number of mips in proj map)
uniform float proj_range; //range between near clip and far clip plane of projection
uniform float proj_ambient_lod;
uniform float proj_ambiance;
uniform float near_clip;
uniform float far_clip;
uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
uniform float sun_wash;
uniform int proj_shadow_idx;
uniform float shadow_fade;
varying vec4 vary_light;
@ -40,6 +44,52 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
vec2 dist = tc-vec2(0.5);
float det = max(1.0-lod/(proj_lod*0.5), 0.0);
float d = dot(dist,dist);
ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0);
return ret;
}
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
float det = min(lod/(proj_lod*0.5), 1.0);
float d = min(dist.x, dist.y);
float edge = 0.25*det;
ret *= clamp(d/edge, 0.0, 1.0);
return ret;
}
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
vec2 dist = tc-vec2(0.5);
float d = dot(dist,dist);
ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
return ret;
}
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).a;
@ -68,7 +118,7 @@ void main()
{
discard;
}
vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0;
norm = normalize(norm);
@ -83,7 +133,11 @@ void main()
proj_tc.xyz /= proj_tc.w;
float fa = gl_Color.a+1.0;
float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
if (dist_atten <= 0.0)
{
discard;
}
lv = proj_origin-pos.xyz;
lv = normalize(lv);
@ -101,32 +155,32 @@ void main()
proj_tc.y > 0.0)
{
float lit = 0.0;
float amb_da = proj_ambiance;
if (da > 0.0)
{
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
float lod = diff * proj_lod;
vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a;
lit = da * dist_atten * noise;
col = lcol*lit*diff_tex;
amb_da += (da*0.5)*proj_ambiance;
}
float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
float lod = diff * proj_lod;
vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
//float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0));
float amb_da = proj_ambiance;
//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
amb_da += (da*da*0.5+0.5)*proj_ambiance;
amb_da *= dist_atten * noise;
amb_da = min(amb_da, 1.0-lit);
col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
}
@ -144,35 +198,28 @@ void main()
{
vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz;
vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
if (stc.z > 0.0)
{
stc.xy /= stc.z+proj_near;
stc.xy /= stc.w;
float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
if (stc.x < 1.0 &&
stc.y < 1.0 &&
stc.x > 0.0 &&
stc.y > 0.0)
{
vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb;
}
}
}
}
/*if (spec.a > 0.0)
{
//vec3 ref = reflect(normalize(pos), norm);
float sa = dot(normalize(lv-normalize(pos)),norm);;
//sa = max(sa, 0.0);
//sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0);
sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0);
sa *= noise;
col += da*sa*lcol*spec.rgb;
}*/
gl_FragColor.rgb = col;
gl_FragColor.a = 0.0;
}

View File

@ -55,7 +55,8 @@ void main()
discard;
}
vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0;
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
float da = dot(norm, lv);
if (da < 0.0)
{

View File

@ -38,10 +38,10 @@ vec4 getPosition(vec2 pos_screen)
void main()
{
vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0;
vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz;
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
vec3 pos = getPosition(vary_fragcoord.xy).xyz;
vec3 ccol = texture2DRect(giLightMap, vary_fragcoord.xy).rgb;
vec2 dlt = kern_scale * delta/(1.0+norm.xy*norm.xy);
dlt /= max(-pos.z*dist_factor, 1.0);
@ -51,9 +51,10 @@ void main()
for (int i = 0; i < kern_length; i++)
{
vec2 tc = vary_fragcoord.xy + kern[i].y*dlt;
vec3 sampNorm = texture2DRect(normalMap, tc.xy).xyz*2.0-1.0;
vec3 sampNorm = texture2DRect(normalMap, tc.xy).xyz;
sampNorm = vec3((sampNorm.xy-0.5)*2.0,sampNorm.z); // unpack norm
float d = dot(norm.xyz, sampNorm);
float d = dot(norm.xyz, sampNorm);
if (d > 0.8)
{

View File

@ -11,6 +11,7 @@ uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect positionMap;
uniform sampler2DRect normalMap;
uniform sampler2DRect lightMap;
uniform sampler2DRect depthMap;
uniform sampler2D noiseMap;
uniform samplerCube environmentMap;
@ -40,7 +41,7 @@ uniform float scene_light_strength;
uniform vec3 env_mat[3];
//uniform mat4 shadow_matrix[3];
//uniform vec4 shadow_clip;
//uniform mat3 ssao_effect_mat;
uniform mat3 ssao_effect_mat;
varying vec4 vary_light;
varying vec2 vary_fragcoord;
@ -55,9 +56,8 @@ vec3 vary_AtmosAttenuation;
uniform mat4 inv_proj;
uniform vec2 screen_res;
vec4 getPosition(vec2 pos_screen)
{ //get position in screen space (world units) given window coordinate and depth map
float depth = texture2DRect(depthMap, pos_screen.xy).a;
vec4 getPosition_d(vec2 pos_screen, float depth)
{
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
@ -68,6 +68,12 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
vec4 getPosition(vec2 pos_screen)
{ //get position in screen space (world units) given window coordinate and depth map
float depth = texture2DRect(depthMap, pos_screen.xy).a;
return getPosition_d(pos_screen, depth);
}
vec3 getPositionEye()
{
return vary_PositionEye;
@ -178,7 +184,17 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
temp2.x += .25;
//increase ambient when there are more clouds
vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5;
vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5;
/* decrease value and saturation (that in HSV, not HSL) for occluded areas
* // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
* // The following line of code performs the equivalent of:
* float ambAlpha = tmpAmbient.a;
* float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
* vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
* tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
*/
tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
//haze color
setAdditiveColor(
@ -241,8 +257,10 @@ vec3 scaleSoftClip(vec3 light)
void main()
{
vec2 tc = vary_fragcoord.xy;
vec3 pos = getPosition(tc).xyz;
vec3 norm = texture2DRect(normalMap, tc).xyz*2.0-1.0;
float depth = texture2DRect(depthMap, tc.xy).a;
vec3 pos = getPosition_d(tc, depth).xyz;
vec3 norm = texture2DRect(normalMap, tc).xyz;
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
//vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz;
float da = max(dot(norm.xyz, vary_light.xyz), 0.0);
@ -250,23 +268,76 @@ void main()
vec4 diffuse = texture2DRect(diffuseRect, tc);
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
calcAtmospherics(pos.xyz, 0.0);
vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
float scol = max(scol_ambocc.r, diffuse.a);
float ambocc = scol_ambocc.g;
calcAtmospherics(pos.xyz, ambocc);
vec3 col = atmosAmbient(vec3(0));
col += atmosAffectDirectionalLight(clamp(da, diffuse.a, 1.0));
col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a));
col *= diffuse.rgb;
if (spec.a > 0.0)
if (spec.a > 0.0) // specular reflection
{
vec3 ref = normalize(reflect(pos.xyz, norm.xyz));
float sa = dot(ref, vary_light.xyz);
col.rgb += vary_SunlitColor*spec.rgb*texture2D(lightFunc, vec2(sa, spec.a)).a;
// the old infinite-sky shiny reflection
//
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
float sa = dot(refnormpersp, vary_light.xyz);
vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a;
/*
// screen-space cheap fakey reflection map
//
vec3 refnorm = normalize(reflect(vec3(0,0,-1), norm.xyz));
depth -= 0.5; // unbias depth
// first figure out where we'll make our 2D guess from
vec2 ref2d = (0.25 * screen_res.y) * (refnorm.xy) * abs(refnorm.z) / depth;
// Offset the guess source a little according to a trivial
// checkerboard dither function and spec.a.
// This is meant to be similar to sampling a blurred version
// of the diffuse map. LOD would be better in that regard.
// The goal of the blur is to soften reflections in surfaces
// with low shinyness, and also to disguise our lameness.
float checkerboard = floor(mod(tc.x+tc.y, 2.0)); // 0.0, 1.0
float checkoffset = (3.0 + (7.0*(1.0-spec.a)))*(checkerboard-0.5);
ref2d += vec2(checkoffset, checkoffset);
ref2d += tc.xy; // use as offset from destination
// Get attributes from the 2D guess point.
// We average two samples of diffuse (not of anything else) per
// pixel to try to reduce aliasing some more.
vec3 refcol = 0.5 * (texture2DRect(diffuseRect, ref2d + vec2(0.0, -checkoffset)).rgb +
texture2DRect(diffuseRect, ref2d + vec2(-checkoffset, 0.0)).rgb);
float refdepth = texture2DRect(depthMap, ref2d).a;
vec3 refpos = getPosition_d(ref2d, refdepth).xyz;
vec3 refn = texture2DRect(normalMap, ref2d).rgb;
refn = normalize(vec3((refn.xy-0.5)*2.0,refn.z)); // unpack norm
// figure out how appropriate our guess actually was
float refapprop = max(0.0, dot(-refnorm, normalize(pos - refpos)));
// darken reflections from points which face away from the reflected ray - our guess was a back-face
//refapprop *= step(dot(refnorm, refn), 0.0);
refapprop = min(refapprop, max(0.0, -dot(refnorm, refn))); // more conservative variant
// get appropriate light strength for guess-point.
// reflect light direction to increase the illusion that
// these are reflections.
vec3 reflight = reflect(lightnorm.xyz, norm.xyz);
float reflit = max(dot(refn, reflight.xyz), 0.0);
// apply sun color to guess-point, dampen according to inappropriateness of guess
float refmod = min(refapprop, reflit);
vec3 refprod = vary_SunlitColor * refcol.rgb * refmod;
vec3 ssshiny = (refprod * spec.a);
ssshiny *= 0.3; // dampen it even more
*/
vec3 ssshiny = vec3(0,0,0);
// add the two types of shiny together
col += (ssshiny + dumbshiny) * spec.rgb;
}
col = atmosLighting(col);
col = scaleSoftClip(col);
gl_FragColor.rgb = col;
gl_FragColor.a = 0.0;
}

View File

@ -68,7 +68,8 @@ void main()
discard;
}
vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0;
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
@ -161,17 +162,6 @@ void main()
}
}
/*if (spec.a > 0.0)
{
//vec3 ref = reflect(normalize(pos), norm);
float sa = dot(normalize(lv-normalize(pos)),norm);;
//sa = max(sa, 0.0);
//sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0);
sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0);
sa *= noise;
col += da*sa*lcol*spec.rgb;
}*/
gl_FragColor.rgb = col;
gl_FragColor.a = 0.0;
}

View File

@ -5,196 +5,11 @@
* $License$
*/
//class 1, no shadow, no SSAO, should never be called
#extension GL_ARB_texture_rectangle : enable
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
uniform sampler2DRectShadow shadowMap0;
uniform sampler2DRectShadow shadowMap1;
uniform sampler2DRectShadow shadowMap2;
uniform sampler2DRectShadow shadowMap3;
uniform sampler2DRectShadow shadowMap4;
uniform sampler2DRectShadow shadowMap5;
uniform sampler2D noiseMap;
uniform sampler2D lightFunc;
// Inputs
uniform mat4 shadow_matrix[6];
uniform vec4 shadow_clip;
uniform float ssao_radius;
uniform float ssao_max_radius;
uniform float ssao_factor;
uniform float ssao_factor_inv;
varying vec2 vary_fragcoord;
varying vec4 vary_light;
uniform mat4 inv_proj;
uniform vec2 screen_res;
uniform float shadow_bias;
uniform float shadow_offset;
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;
}
//calculate decreases in ambient lighting when crowded out (SSAO)
float calcAmbientOcclusion(vec4 pos, vec3 norm)
{
vec2 kern[8];
// exponentially (^2) distant occlusion samples spread around origin
kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
vec2 pos_screen = vary_fragcoord.xy;
vec3 pos_world = pos.xyz;
vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy;
float angle_hidden = 0.0;
int points = 0;
float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
// it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?)
for (int i = 0; i < 8; i++)
{
vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect);
vec3 samppos_world = getPosition(samppos_screen).xyz;
vec3 diff = pos_world - samppos_world;
float dist2 = dot(diff, diff);
// assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
// --> solid angle shrinking by the square of distance
//radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
//(k should vary inversely with # of samples, but this is taken care of later)
//if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) // -0.05*norm to shift sample point back slightly for flat surfaces
// angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional. max of 1.0 (= ssao_factor_inv * ssao_factor)
angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv);
// 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
points = points + int(diff.z > -1.0);
}
angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0);
return (1.0 - (float(points != 0) * angle_hidden));
}
void main()
{
vec2 pos_screen = vary_fragcoord.xy;
//try doing an unproject here
vec4 pos = getPosition(pos_screen);
vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0;
/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL
{
gl_FragColor = vec4(0.0); // doesn't matter
return;
}*/
float shadow = 1.0;
float dp_directional_light = max(0.0, dot(norm, vary_light.xyz));
vec4 spos = vec4(pos.xyz + norm.xyz * (-pos.z/64.0*shadow_offset+shadow_bias), 1.0);
//vec3 debug = vec3(0,0,0);
if (dp_directional_light == 0.0)
{
// if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup
shadow = 0.0;
}
else if (spos.z > -shadow_clip.w)
{
vec4 lpos;
if (spos.z < -shadow_clip.z)
{
lpos = shadow_matrix[3]*spos;
lpos.xy *= screen_res;
shadow = shadow2DRectProj(shadowMap3, lpos).x;
shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
}
else if (spos.z < -shadow_clip.y)
{
lpos = shadow_matrix[2]*spos;
lpos.xy *= screen_res;
shadow = shadow2DRectProj(shadowMap2, lpos).x;
}
else if (spos.z < -shadow_clip.x)
{
lpos = shadow_matrix[1]*spos;
lpos.xy *= screen_res;
shadow = shadow2DRectProj(shadowMap1, lpos).x;
}
else
{
lpos = shadow_matrix[0]*spos;
lpos.xy *= screen_res;
shadow = shadow2DRectProj(shadowMap0, lpos).x;
}
// take the most-shadowed value out of these two:
// * the blurred sun shadow in the light (shadow) map
// * an unblurred dot product between the sun and this norm
// the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting
shadow = min(shadow, dp_directional_light);
/*debug.r = lpos.y / (lpos.w*screen_res.y);
lpos.xy /= lpos.w*32.0;
if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1)
{
debug.gb = vec2(0.5, 0.5);
}
debug += (1.0-shadow)*0.5;*/
}
else
{
// more distant than the shadow map covers - just use directional shading as shadow
shadow = dp_directional_light;
}
gl_FragColor[0] = shadow;
gl_FragColor[1] = calcAmbientOcclusion(pos, norm);
//spotlight shadow 1
vec4 lpos = shadow_matrix[4]*spos;
lpos.xy *= screen_res;
gl_FragColor[2] = shadow2DRectProj(shadowMap4, lpos).x;
//spotlight shadow 2
lpos = shadow_matrix[5]*spos;
lpos.xy *= screen_res;
gl_FragColor[3] = shadow2DRectProj(shadowMap5, lpos).x;
//gl_FragColor.rgb = pos.xyz;
//gl_FragColor.b = shadow;
//gl_FragColor.rgb = debug;
gl_FragColor = vec4(0,0,0,0);
}

View File

@ -0,0 +1,124 @@
/**
* @file sunLightSSAOF.glsl
*
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
* $License$
*/
#extension GL_ARB_texture_rectangle : enable
//class 1 -- no shadow, SSAO only
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
uniform sampler2D noiseMap;
uniform sampler2D lightFunc;
// Inputs
uniform mat4 shadow_matrix[6];
uniform vec4 shadow_clip;
uniform float ssao_radius;
uniform float ssao_max_radius;
uniform float ssao_factor;
uniform float ssao_factor_inv;
varying vec2 vary_fragcoord;
varying vec4 vary_light;
uniform mat4 inv_proj;
uniform vec2 screen_res;
uniform float shadow_bias;
uniform float shadow_offset;
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;
}
//calculate decreases in ambient lighting when crowded out (SSAO)
float calcAmbientOcclusion(vec4 pos, vec3 norm)
{
float ret = 1.0;
float dist = dot(pos.xyz,pos.xyz);
if (dist < 64.0*64.0)
{
vec2 kern[8];
// exponentially (^2) distant occlusion samples spread around origin
kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
vec2 pos_screen = vary_fragcoord.xy;
vec3 pos_world = pos.xyz;
vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy;
float angle_hidden = 0.0;
int points = 0;
float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
// it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?)
for (int i = 0; i < 8; i++)
{
vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect);
vec3 samppos_world = getPosition(samppos_screen).xyz;
vec3 diff = pos_world - samppos_world;
float dist2 = dot(diff, diff);
// assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
// --> solid angle shrinking by the square of distance
//radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
//(k should vary inversely with # of samples, but this is taken care of later)
//if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) // -0.05*norm to shift sample point back slightly for flat surfaces
// angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional. max of 1.0 (= ssao_factor_inv * ssao_factor)
angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv);
// 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
points = points + int(diff.z > -1.0);
}
angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0);
ret = (1.0 - (float(points != 0) * angle_hidden));
ret += max((dist-32.0*32.0)/(32.0*32.0), 0.0);
}
return min(ret, 1.0);
}
void main()
{
vec2 pos_screen = vary_fragcoord.xy;
//try doing an unproject here
vec4 pos = getPosition(pos_screen);
vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
gl_FragColor[0] = 1.0;
gl_FragColor[1] = calcAmbientOcclusion(pos, norm);
gl_FragColor[2] = 1.0;
gl_FragColor[3] = 1.0;
}

View File

@ -29,6 +29,7 @@ void main()
gl_FragData[0] = vec4(outColor.rgb, 0.0);
gl_FragData[1] = vec4(outColor.rgb*0.2, 0.2);
gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0);
vec3 nvn = normalize(vary_normal);
gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
}

View File

@ -14,5 +14,6 @@ void main()
vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy);
gl_FragData[0] = vec4(gl_Color.rgb*col.rgb, col.a <= 0.5 ? 0.0 : 0.005);
gl_FragData[1] = vec4(0,0,0,0);
gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0);
vec3 nvn = normalize(vary_normal);
gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
}

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