merged .hgtags & BuildParams
commit
fcf2ed5901
1
.hgtags
1
.hgtags
|
|
@ -133,3 +133,4 @@ dac76a711da5f1489a01c1fa62ec97d99c25736d 2.6.6-release
|
|||
e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb DRTVWR-63_2.7.2-beta1
|
||||
e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb 2.7.2-beta1
|
||||
6a3e7e403bd19e45fdfc2fcc716867af3ab80861 2.7.3-start
|
||||
6af10678de4736222b2c3f7e010e984fb5b327de 2.7.4-start
|
||||
|
|
|
|||
15
BuildParams
15
BuildParams
|
|
@ -101,6 +101,16 @@ mesh-development.build_debug_release_separately = true
|
|||
mesh-development.build_CYGWIN_Debug = false
|
||||
mesh-development.build_viewer_update_version_manager = false
|
||||
|
||||
# ========================================
|
||||
# mesh-asset-deprecation
|
||||
# ========================================
|
||||
mesh-asset-deprecation.viewer_channel = "Project Viewer - Mesh Asset Deprecation"
|
||||
mesh-asset-deprecation.login_channel = "Project Viewer - Mesh Asset Deprecation"
|
||||
mesh-asset-deprecation.viewer_grid = aditi
|
||||
mesh-asset-deprecation.build_debug_release_separately = true
|
||||
mesh-asset-deprecation.build_CYGWIN_Debug = false
|
||||
mesh-asset-deprecation.build_viewer_update_version_manager = false
|
||||
|
||||
# ========================================
|
||||
# viewer-mesh
|
||||
# ========================================
|
||||
|
|
@ -177,9 +187,10 @@ oz_viewer-devreview.build_debug_release_separately = true
|
|||
oz_project-1.build_debug_release_separately = true
|
||||
oz_project-2.build_debug_release_separately = true
|
||||
oz-project-3.build_debug_release_separately = true
|
||||
|
||||
|
||||
oz_viewer-beta-review.build_debug_release_separately = true
|
||||
oz_viewer-poreview.build_debug_release_separately = true
|
||||
oz_viewer-poreview.codeticket_add_context = false
|
||||
|
||||
# ========================================
|
||||
# enus
|
||||
# ========================================
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>930bdd987a321eda1838caba8cd6098f</string>
|
||||
<string>b2fe1c860613a68e74d4384be418ffee</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/230348/arch/Darwin/installer/glod-1.0pre4-darwin-20110519.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/232684/arch/Darwin/installer/glod-1.0pre4-darwin-20110610.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin</string>
|
||||
|
|
@ -30,9 +30,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>fb33b6cac2e6b98f93c5efa2af2e5a00</string>
|
||||
<string>c0c64dae149d0892343e2ff300fd06b9</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/230348/arch/Linux/installer/glod-1.0pre4-linux-20110519.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/232684/arch/Linux/installer/glod-1.0pre4-linux-20110611.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux</string>
|
||||
|
|
@ -42,9 +42,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>388cf0e292f756b4bb37696622f0bbc5</string>
|
||||
<string>842208365f5b108dac4c7c733b99da9c</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/230348/arch/CYGWIN/installer/glod-1.0pre4-windows-20110519.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/232684/arch/CYGWIN/installer/glod-1.0pre4-windows-20110610.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -1290,9 +1290,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>c81bacf922bb3b540d92b660364c48ce</string>
|
||||
<string>9bf7a96c1d2fadb180fda91740c945c6</string>
|
||||
<key>url</key>
|
||||
<string>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ndofdev-linux-0.2-20101013.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-libndofdev-linux/rev/233137/arch/Linux/installer/libndofdev-0.3-linux-20110617.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux</string>
|
||||
|
|
@ -1524,7 +1524,7 @@
|
|||
<key>hash</key>
|
||||
<string>bb0abe962b3b8208ed2dab0424aab33d</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-pcre/rev/228822/arch/Linux/installer/pcre-7.6-linux-20110504.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-pcre/rev/228822/arch/Linux/installer/pcre-7.6-linux-20110504.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux</string>
|
||||
|
|
|
|||
|
|
@ -442,6 +442,10 @@ Jonathan Yap
|
|||
STORM-1095
|
||||
STORM-1236
|
||||
STORM-1259
|
||||
STORM-787
|
||||
STORM-1313
|
||||
STORM-899
|
||||
STORM-1273
|
||||
Kage Pixel
|
||||
VWR-11
|
||||
Ken March
|
||||
|
|
@ -851,6 +855,7 @@ Twisted Laws
|
|||
STORM-844
|
||||
STORM-643
|
||||
STORM-954
|
||||
STORM-1103
|
||||
Vadim Bigbear
|
||||
VWR-2681
|
||||
Vector Hastings
|
||||
|
|
|
|||
|
|
@ -29,30 +29,38 @@
|
|||
|
||||
struct ParcelQuota
|
||||
{
|
||||
ParcelQuota( F32 ownerRenderCost, F32 ownerPhysicsCost, F32 ownerNetworkCost, F32 ownerSimulationCost,
|
||||
F32 groupRenderCost, F32 groupPhysicsCost, F32 groupNetworkCost, F32 groupSimulationCost,
|
||||
F32 otherRenderCost, F32 otherPhysicsCost, F32 otherNetworkCost, F32 otherSimulationCost,
|
||||
F32 totalRenderCost, F32 totalPhysicsCost, F32 totalNetworkCost, F32 totalSimulationCost)
|
||||
ParcelQuota( F32 ownerRenderCost, F32 ownerPhysicsCost, F32 ownerNetworkCost, F32 ownerSimulationCost,
|
||||
F32 groupRenderCost, F32 groupPhysicsCost, F32 groupNetworkCost, F32 groupSimulationCost,
|
||||
F32 otherRenderCost, F32 otherPhysicsCost, F32 otherNetworkCost, F32 otherSimulationCost,
|
||||
F32 tempRenderCost, F32 tempPhysicsCost, F32 tempNetworkCost, F32 tempSimulationCost,
|
||||
F32 selectedRenderCost, F32 selectedPhysicsCost, F32 selectedNetworkCost, F32 selectedSimulationCost,
|
||||
F32 parcelCapacity )
|
||||
: mOwnerRenderCost( ownerRenderCost ), mOwnerPhysicsCost( ownerPhysicsCost )
|
||||
, mOwnerNetworkCost( ownerNetworkCost ), mOwnerSimulationCost( ownerSimulationCost )
|
||||
, mGroupRenderCost( groupRenderCost ), mGroupPhysicsCost( groupPhysicsCost )
|
||||
, mGroupNetworkCost( groupNetworkCost ), mGroupSimulationCost( groupSimulationCost )
|
||||
, mOtherRenderCost( otherRenderCost ), mOtherPhysicsCost( otherPhysicsCost )
|
||||
, mOtherNetworkCost( otherNetworkCost ), mOtherSimulationCost( otherSimulationCost )
|
||||
, mTotalRenderCost( totalRenderCost ), mTotalPhysicsCost( totalPhysicsCost )
|
||||
, mTotalNetworkCost( totalNetworkCost ), mTotalSimulationCost( totalSimulationCost )
|
||||
, mTempRenderCost( tempRenderCost ), mTempPhysicsCost( tempPhysicsCost )
|
||||
, mTempNetworkCost( tempNetworkCost ), mTempSimulationCost( tempSimulationCost )
|
||||
, mSelectedRenderCost( tempRenderCost ), mSelectedPhysicsCost( tempPhysicsCost )
|
||||
, mSelectedNetworkCost( tempNetworkCost ), mSelectedSimulationCost( selectedSimulationCost )
|
||||
, mParcelCapacity( parcelCapacity )
|
||||
{
|
||||
}
|
||||
|
||||
ParcelQuota(){}
|
||||
F32 mOwnerRenderCost, mOwnerPhysicsCost, mOwnerNetworkCost, mOwnerSimulationCost;
|
||||
F32 mGroupRenderCost, mGroupPhysicsCost, mGroupNetworkCost, mGroupSimulationCost;
|
||||
F32 mOtherRenderCost, mOtherPhysicsCost, mOtherNetworkCost, mOtherSimulationCost;
|
||||
F32 mTotalRenderCost, mTotalPhysicsCost, mTotalNetworkCost, mTotalSimulationCost;
|
||||
F32 mTempRenderCost, mTempPhysicsCost, mTempNetworkCost, mTempSimulationCost;
|
||||
F32 mSelectedRenderCost, mSelectedPhysicsCost, mSelectedNetworkCost, mSelectedSimulationCost;
|
||||
F32 mParcelCapacity;
|
||||
};
|
||||
|
||||
struct SelectionQuota
|
||||
{
|
||||
SelectionQuota( S32 localId, F32 renderCost, F32 physicsCost, F32 networkCost, F32 simulationCost )
|
||||
SelectionQuota( LLUUID localId, F32 renderCost, F32 physicsCost, F32 networkCost, F32 simulationCost )
|
||||
: mLocalId( localId)
|
||||
, mRenderCost( renderCost )
|
||||
, mPhysicsCost( physicsCost )
|
||||
|
|
@ -63,7 +71,7 @@ struct SelectionQuota
|
|||
SelectionQuota() {}
|
||||
|
||||
F32 mRenderCost, mPhysicsCost, mNetworkCost, mSimulationCost;
|
||||
S32 mLocalId;
|
||||
LLUUID mLocalId;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2036,7 +2036,9 @@ std::string zip_llsd(LLSD& data)
|
|||
{ //copy result into output
|
||||
if (strm.avail_out >= CHUNK)
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
free(output);
|
||||
llwarns << "Failed to compress LLSD block." << llendl;
|
||||
return std::string();
|
||||
}
|
||||
|
||||
have = CHUNK-strm.avail_out;
|
||||
|
|
|
|||
|
|
@ -737,7 +737,7 @@ void LLPerfBlock::addStatsToLLSDandReset( LLSD & stats,
|
|||
}
|
||||
}
|
||||
else
|
||||
{ // WTF? Shouldn't have a NULL pointer in the map.
|
||||
{ // Shouldn't have a NULL pointer in the map.
|
||||
llwarns << "Unexpected NULL dynamic stat at '" << stats_full_path << "'" << llendl;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
const S32 LL_VERSION_MAJOR = 2;
|
||||
const S32 LL_VERSION_MINOR = 7;
|
||||
const S32 LL_VERSION_PATCH = 3;
|
||||
const S32 LL_VERSION_PATCH = 4;
|
||||
const S32 LL_VERSION_BUILD = 0;
|
||||
|
||||
const char * const LL_CHANNEL = "Second Life Developer";
|
||||
|
|
|
|||
|
|
@ -35,12 +35,14 @@
|
|||
|
||||
#define OCT_ERRS LL_WARNS("OctreeErrors")
|
||||
|
||||
#define LL_OCTREE_PARANOIA_CHECK 0
|
||||
|
||||
extern U32 gOctreeMaxCapacity;
|
||||
/*#define LL_OCTREE_PARANOIA_CHECK 0
|
||||
#if LL_DARWIN
|
||||
#define LL_OCTREE_MAX_CAPACITY 32
|
||||
#else
|
||||
#define LL_OCTREE_MAX_CAPACITY 128
|
||||
#endif
|
||||
#endif*/
|
||||
|
||||
template <class T> class LLOctreeNode;
|
||||
|
||||
|
|
@ -74,6 +76,7 @@ template <class T>
|
|||
class LLOctreeNode : public LLTreeNode<T>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef LLOctreeTraveler<T> oct_traveler;
|
||||
typedef LLTreeTraveler<T> tree_traveler;
|
||||
typedef typename std::set<LLPointer<T> > element_list;
|
||||
|
|
@ -294,8 +297,8 @@ public:
|
|||
//is it here?
|
||||
if (isInside(data->getPositionGroup()))
|
||||
{
|
||||
if ((getElementCount() < LL_OCTREE_MAX_CAPACITY && contains(data->getBinRadius()) ||
|
||||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= LL_OCTREE_MAX_CAPACITY)))
|
||||
if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) ||
|
||||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
|
||||
{ //it belongs here
|
||||
#if LL_OCTREE_PARANOIA_CHECK
|
||||
//if this is a redundant insertion, error out (should never happen)
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ void assert_aligned(void* ptr, uintptr_t alignment)
|
|||
uintptr_t t = (uintptr_t) ptr;
|
||||
if (t%alignment != 0)
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
llerrs << "Alignment check failed." << llendl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -361,7 +361,7 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
llerrs << "WTF? Empty leaf" << llendl;
|
||||
llerrs << "Empty leaf" << llendl;
|
||||
}
|
||||
|
||||
for (S32 i = 0; i < branch->getChildCount(); ++i)
|
||||
|
|
@ -416,6 +416,70 @@ LLProfile::Face* LLProfile::addFace(S32 i, S32 count, F32 scaleU, S16 faceID, BO
|
|||
return face;
|
||||
}
|
||||
|
||||
//static
|
||||
S32 LLProfile::getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset, F32 bevel, F32 ang_scale, S32 split)
|
||||
{ // this is basically LLProfile::genNGon stripped down to only the operations that influence the number of points
|
||||
LLMemType m1(LLMemType::MTYPE_VOLUME);
|
||||
S32 np = 0;
|
||||
|
||||
// Generate an n-sided "circular" path.
|
||||
// 0 is (1,0), and we go counter-clockwise along a circular path from there.
|
||||
F32 t, t_step, t_first, t_fraction;
|
||||
|
||||
F32 begin = params.getBegin();
|
||||
F32 end = params.getEnd();
|
||||
|
||||
t_step = 1.0f / sides;
|
||||
|
||||
t_first = floor(begin * sides) / (F32)sides;
|
||||
|
||||
// pt1 is the first point on the fractional face.
|
||||
// Starting t and ang values for the first face
|
||||
t = t_first;
|
||||
|
||||
// Increment to the next point.
|
||||
// pt2 is the end point on the fractional face
|
||||
t += t_step;
|
||||
|
||||
t_fraction = (begin - t_first)*sides;
|
||||
|
||||
// Only use if it's not almost exactly on an edge.
|
||||
if (t_fraction < 0.9999f)
|
||||
{
|
||||
np++;
|
||||
}
|
||||
|
||||
// There's lots of potential here for floating point error to generate unneeded extra points - DJS 04/05/02
|
||||
while (t < end)
|
||||
{
|
||||
// Iterate through all the integer steps of t.
|
||||
np++;
|
||||
|
||||
t += t_step;
|
||||
}
|
||||
|
||||
t_fraction = (end - (t - t_step))*sides;
|
||||
|
||||
// Find the fraction that we need to add to the end point.
|
||||
t_fraction = (end - (t - t_step))*sides;
|
||||
if (t_fraction > 0.0001f)
|
||||
{
|
||||
np++;
|
||||
}
|
||||
|
||||
// If we're sliced, the profile is open.
|
||||
if ((end - begin)*ang_scale < 0.99f)
|
||||
{
|
||||
if (params.getHollow() <= 0)
|
||||
{
|
||||
// put center point if not hollow.
|
||||
np++;
|
||||
}
|
||||
}
|
||||
|
||||
return np;
|
||||
}
|
||||
|
||||
// What is the bevel parameter used for? - DJS 04/05/02
|
||||
// Bevel parameter is currently unused but presumedly would support
|
||||
// filleted and chamfered corners
|
||||
|
|
@ -672,6 +736,117 @@ LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F3
|
|||
return face;
|
||||
}
|
||||
|
||||
//static
|
||||
S32 LLProfile::getNumPoints(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split,
|
||||
BOOL is_sculpted, S32 sculpt_size)
|
||||
{ // this is basically LLProfile::generate stripped down to only operations that influence the number of points
|
||||
LLMemType m1(LLMemType::MTYPE_VOLUME);
|
||||
|
||||
if (detail < MIN_LOD)
|
||||
{
|
||||
detail = MIN_LOD;
|
||||
}
|
||||
|
||||
// Generate the face data
|
||||
F32 hollow = params.getHollow();
|
||||
|
||||
S32 np = 0;
|
||||
|
||||
switch (params.getCurveType() & LL_PCODE_PROFILE_MASK)
|
||||
{
|
||||
case LL_PCODE_PROFILE_SQUARE:
|
||||
{
|
||||
np = getNumNGonPoints(params, 4,-0.375, 0, 1, split);
|
||||
|
||||
if (hollow)
|
||||
{
|
||||
np *= 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LL_PCODE_PROFILE_ISOTRI:
|
||||
case LL_PCODE_PROFILE_RIGHTTRI:
|
||||
case LL_PCODE_PROFILE_EQUALTRI:
|
||||
{
|
||||
np = getNumNGonPoints(params, 3,0, 0, 1, split);
|
||||
|
||||
if (hollow)
|
||||
{
|
||||
np *= 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LL_PCODE_PROFILE_CIRCLE:
|
||||
{
|
||||
// If this has a square hollow, we should adjust the
|
||||
// number of faces a bit so that the geometry lines up.
|
||||
U8 hole_type=0;
|
||||
F32 circle_detail = MIN_DETAIL_FACES * detail;
|
||||
if (hollow)
|
||||
{
|
||||
hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK;
|
||||
if (hole_type == LL_PCODE_HOLE_SQUARE)
|
||||
{
|
||||
// Snap to the next multiple of four sides,
|
||||
// so that corners line up.
|
||||
circle_detail = llceil(circle_detail / 4.0f) * 4.0f;
|
||||
}
|
||||
}
|
||||
|
||||
S32 sides = (S32)circle_detail;
|
||||
|
||||
if (is_sculpted)
|
||||
sides = sculpt_size;
|
||||
|
||||
np = getNumNGonPoints(params, sides);
|
||||
|
||||
if (hollow)
|
||||
{
|
||||
np *= 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LL_PCODE_PROFILE_CIRCLE_HALF:
|
||||
{
|
||||
// If this has a square hollow, we should adjust the
|
||||
// number of faces a bit so that the geometry lines up.
|
||||
U8 hole_type=0;
|
||||
// Number of faces is cut in half because it's only a half-circle.
|
||||
F32 circle_detail = MIN_DETAIL_FACES * detail * 0.5f;
|
||||
if (hollow)
|
||||
{
|
||||
hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK;
|
||||
if (hole_type == LL_PCODE_HOLE_SQUARE)
|
||||
{
|
||||
// Snap to the next multiple of four sides (div 2),
|
||||
// so that corners line up.
|
||||
circle_detail = llceil(circle_detail / 2.0f) * 2.0f;
|
||||
}
|
||||
}
|
||||
np = getNumNGonPoints(params, llfloor(circle_detail), 0.5f, 0.f, 0.5f);
|
||||
|
||||
if (hollow)
|
||||
{
|
||||
np *= 2;
|
||||
}
|
||||
|
||||
// Special case for openness of sphere
|
||||
if ((params.getEnd() - params.getBegin()) < 1.f)
|
||||
{
|
||||
}
|
||||
else if (!hollow)
|
||||
{
|
||||
np++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
|
||||
return np;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split,
|
||||
|
|
@ -1133,6 +1308,32 @@ LLPath::~LLPath()
|
|||
{
|
||||
}
|
||||
|
||||
S32 LLPath::getNumNGonPoints(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)
|
||||
{ //this is basically LLPath::genNGon stripped down to only operations that influence the number of points added
|
||||
S32 ret = 0;
|
||||
|
||||
F32 step= 1.0f / sides;
|
||||
F32 t = params.getBegin();
|
||||
ret = 1;
|
||||
|
||||
t+=step;
|
||||
|
||||
// Snap to a quantized parameter, so that cut does not
|
||||
// affect most sample points.
|
||||
t = ((S32)(t * sides)) / (F32)sides;
|
||||
|
||||
// Run through the non-cut dependent points.
|
||||
while (t < params.getEnd())
|
||||
{
|
||||
ret++;
|
||||
t+=step;
|
||||
}
|
||||
|
||||
ret++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)
|
||||
{
|
||||
// Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane.
|
||||
|
|
@ -1310,6 +1511,56 @@ const LLVector2 LLPathParams::getEndScale() const
|
|||
return end_scale;
|
||||
}
|
||||
|
||||
S32 LLPath::getNumPoints(const LLPathParams& params, F32 detail)
|
||||
{ // this is basically LLPath::generate stripped down to only the operations that influence the number of points
|
||||
LLMemType m1(LLMemType::MTYPE_VOLUME);
|
||||
|
||||
if (detail < MIN_LOD)
|
||||
{
|
||||
detail = MIN_LOD;
|
||||
}
|
||||
|
||||
S32 np = 2; // hardcode for line
|
||||
|
||||
// Is this 0xf0 mask really necessary? DK 03/02/05
|
||||
|
||||
switch (params.getCurveType() & 0xf0)
|
||||
{
|
||||
default:
|
||||
case LL_PCODE_PATH_LINE:
|
||||
{
|
||||
// Take the begin/end twist into account for detail.
|
||||
np = llfloor(fabs(params.getTwistBegin() - params.getTwist()) * 3.5f * (detail-0.5f)) + 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_PCODE_PATH_CIRCLE:
|
||||
{
|
||||
// Increase the detail as the revolutions and twist increase.
|
||||
F32 twist_mag = fabs(params.getTwistBegin() - params.getTwist());
|
||||
|
||||
S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * params.getRevolutions());
|
||||
|
||||
np = sides;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_PCODE_PATH_CIRCLE2:
|
||||
{
|
||||
//genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f);
|
||||
np = getNumNGonPoints(params, llfloor(MIN_DETAIL_FACES * detail));
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_PCODE_PATH_TEST:
|
||||
|
||||
np = 5;
|
||||
break;
|
||||
};
|
||||
|
||||
return np;
|
||||
}
|
||||
|
||||
BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
|
||||
BOOL is_sculpted, S32 sculpt_size)
|
||||
{
|
||||
|
|
@ -2159,27 +2410,41 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
|
|||
U32 face_count = mdl.size();
|
||||
|
||||
if (face_count == 0)
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
{ //no faces unpacked, treat as failed decode
|
||||
llwarns << "found no faces!" << llendl;
|
||||
return false;
|
||||
}
|
||||
|
||||
mVolumeFaces.resize(face_count);
|
||||
|
||||
for (U32 i = 0; i < face_count; ++i)
|
||||
{
|
||||
LLVolumeFace& face = mVolumeFaces[i];
|
||||
|
||||
if (mdl[i].has("NoGeometry"))
|
||||
{ //face has no geometry, continue
|
||||
face.resizeIndices(3);
|
||||
face.resizeVertices(1);
|
||||
memset(face.mPositions, 0, sizeof(LLVector4a));
|
||||
memset(face.mNormals, 0, sizeof(LLVector4a));
|
||||
memset(face.mTexCoords, 0, sizeof(LLVector2));
|
||||
memset(face.mIndices, 0, sizeof(U16)*3);
|
||||
continue;
|
||||
}
|
||||
|
||||
LLSD::Binary pos = mdl[i]["Position"];
|
||||
LLSD::Binary norm = mdl[i]["Normal"];
|
||||
LLSD::Binary tc = mdl[i]["TexCoord0"];
|
||||
LLSD::Binary idx = mdl[i]["TriangleList"];
|
||||
|
||||
LLVolumeFace& face = mVolumeFaces[i];
|
||||
|
||||
|
||||
//copy out indices
|
||||
face.resizeIndices(idx.size()/2);
|
||||
|
||||
if (idx.empty() || face.mNumIndices < 3)
|
||||
{ //why is there an empty index list?
|
||||
llerrs <<"WTF?" << llendl;
|
||||
llwarns <<"Empty face present!" << llendl;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -2377,14 +2642,20 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
|
|||
LLVector4a& min = face.mExtents[0];
|
||||
LLVector4a& max = face.mExtents[1];
|
||||
|
||||
min.clear();
|
||||
max.clear();
|
||||
min = max = face.mPositions[0];
|
||||
|
||||
for (S32 i = 1; i < face.mNumVertices; ++i)
|
||||
if (face.mNumVertices < 3)
|
||||
{ //empty face, use a dummy 1cm (at 1m scale) bounding box
|
||||
min.splat(-0.005f);
|
||||
max.splat(0.005f);
|
||||
}
|
||||
else
|
||||
{
|
||||
min.setMin(min, face.mPositions[i]);
|
||||
max.setMax(max, face.mPositions[i]);
|
||||
min = max = face.mPositions[0];
|
||||
|
||||
for (S32 i = 1; i < face.mNumVertices; ++i)
|
||||
{
|
||||
min.setMin(min, face.mPositions[i]);
|
||||
max.setMax(max, face.mPositions[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2980,7 +3251,11 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components,
|
|||
// don't test lowest LOD to support legacy content DEV-33670
|
||||
if (mDetail > SCULPT_MIN_AREA_DETAIL)
|
||||
{
|
||||
if (sculptGetSurfaceArea() < SCULPT_MIN_AREA)
|
||||
F32 area = sculptGetSurfaceArea();
|
||||
|
||||
const F32 SCULPT_MAX_AREA = 32.f;
|
||||
|
||||
if (area < SCULPT_MIN_AREA || area > SCULPT_MAX_AREA)
|
||||
{
|
||||
data_is_empty = TRUE;
|
||||
}
|
||||
|
|
@ -4064,6 +4339,23 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
|
|||
return index;
|
||||
}
|
||||
|
||||
void LLVolume::getLoDTriangleCounts(const LLVolumeParams& params, S32* counts)
|
||||
{ //attempt to approximate the number of triangles that will result from generating a volume LoD set for the
|
||||
//supplied LLVolumeParams -- inaccurate, but a close enough approximation for determining streaming cost
|
||||
F32 detail[] = {1.f, 1.5f, 2.5f, 4.f};
|
||||
for (S32 i = 0; i < 4; i++)
|
||||
{
|
||||
S32 count = 0;
|
||||
S32 path_points = LLPath::getNumPoints(params.getPathParams(), detail[i]);
|
||||
S32 profile_points = LLProfile::getNumPoints(params.getProfileParams(), false, detail[i]);
|
||||
|
||||
count = (profile_points-1)*2*(path_points-1);
|
||||
count += profile_points*2;
|
||||
|
||||
counts[i] = count;
|
||||
}
|
||||
}
|
||||
|
||||
S32 LLVolume::getNumTriangleIndices() const
|
||||
{
|
||||
BOOL profile_open = getProfile().isOpen();
|
||||
|
|
@ -5220,6 +5512,8 @@ LLVolumeFace::LLVolumeFace() :
|
|||
mOctree(NULL)
|
||||
{
|
||||
mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);
|
||||
mExtents[0].splat(-0.5f);
|
||||
mExtents[1].splat(0.5f);
|
||||
mCenter = mExtents+2;
|
||||
}
|
||||
|
||||
|
|
@ -5741,6 +6035,11 @@ void LLVolumeFace::cacheOptimize()
|
|||
|
||||
LLVCacheLRU cache;
|
||||
|
||||
if (mNumVertices < 3)
|
||||
{ //nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
//mapping of vertices to triangles and indices
|
||||
std::vector<LLVCacheVertexData> vertex_data;
|
||||
|
||||
|
|
|
|||
|
|
@ -690,6 +690,9 @@ public:
|
|||
BOOL isFlat(S32 face) const { return (mFaces[face].mCount == 2); }
|
||||
BOOL isOpen() const { return mOpen; }
|
||||
void setDirty() { mDirty = TRUE; }
|
||||
|
||||
static S32 getNumPoints(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0,
|
||||
BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
|
||||
BOOL generate(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0,
|
||||
BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
|
||||
BOOL isConcave() const { return mConcave; }
|
||||
|
|
@ -714,6 +717,7 @@ public:
|
|||
|
||||
protected:
|
||||
void genNormals(const LLProfileParams& params);
|
||||
static S32 getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
|
||||
void genNGon(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
|
||||
|
||||
Face* addHole(const LLProfileParams& params, BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split = 0);
|
||||
|
|
@ -756,6 +760,9 @@ public:
|
|||
|
||||
virtual ~LLPath();
|
||||
|
||||
static S32 getNumPoints(const LLPathParams& params, F32 detail);
|
||||
static S32 getNumNGonPoints(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f);
|
||||
|
||||
void genNGon(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f);
|
||||
virtual BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0,
|
||||
BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
|
||||
|
|
@ -981,6 +988,7 @@ public:
|
|||
|
||||
// returns number of triangle indeces required for path/profile mesh
|
||||
S32 getNumTriangleIndices() const;
|
||||
static void getLoDTriangleCounts(const LLVolumeParams& params, S32* counts);
|
||||
|
||||
S32 getNumTriangles() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -742,6 +742,7 @@ char const* const _PREHASH_MoneyData = LLMessageStringTable::getInstance()->getS
|
|||
char const* const _PREHASH_ObjectDeselect = LLMessageStringTable::getInstance()->getString("ObjectDeselect");
|
||||
char const* const _PREHASH_NewAssetID = LLMessageStringTable::getInstance()->getString("NewAssetID");
|
||||
char const* const _PREHASH_ObjectAdd = LLMessageStringTable::getInstance()->getString("ObjectAdd");
|
||||
char const* const _PREHASH_SimulatorFeatures = LLMessageStringTable::getInstance()->getString("SimulatorFeatures");
|
||||
char const* const _PREHASH_RayEndIsIntersection = LLMessageStringTable::getInstance()->getString("RayEndIsIntersection");
|
||||
char const* const _PREHASH_CompleteAuction = LLMessageStringTable::getInstance()->getString("CompleteAuction");
|
||||
char const* const _PREHASH_CircuitCode = LLMessageStringTable::getInstance()->getString("CircuitCode");
|
||||
|
|
|
|||
|
|
@ -742,6 +742,7 @@ extern char const* const _PREHASH_MoneyData;
|
|||
extern char const* const _PREHASH_ObjectDeselect;
|
||||
extern char const* const _PREHASH_NewAssetID;
|
||||
extern char const* const _PREHASH_ObjectAdd;
|
||||
extern char const* const _PREHASH_SimulatorFeatures;
|
||||
extern char const* const _PREHASH_RayEndIsIntersection;
|
||||
extern char const* const _PREHASH_CompleteAuction;
|
||||
extern char const* const _PREHASH_CircuitCode;
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ std::string model_names[] =
|
|||
"low_lod",
|
||||
"medium_lod",
|
||||
"high_lod",
|
||||
"physics_shape"
|
||||
"physics_mesh"
|
||||
};
|
||||
|
||||
const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string);
|
||||
|
|
@ -84,7 +84,7 @@ void load_face_from_dom_inputs(LLVolumeFace& face, const domInputLocalOffset_Arr
|
|||
domInputLocal_Array& v_inp = vertices->getInput_array();
|
||||
if (inputs[j]->getOffset() != 0)
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
llerrs << "Vertex array offset MUST be zero." << llendl;
|
||||
}
|
||||
|
||||
for (U32 k = 0; k < v_inp.getCount(); ++k)
|
||||
|
|
@ -98,7 +98,7 @@ void load_face_from_dom_inputs(LLVolumeFace& face, const domInputLocalOffset_Arr
|
|||
|
||||
if (src->getTechnique_common()->getAccessor()->getStride() != 3)
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
llerrs << "Vertex array stride MUST be three." << llendl;
|
||||
}
|
||||
|
||||
domListOfFloats& v = src->getFloat_array()->getValue();
|
||||
|
|
@ -149,9 +149,10 @@ void load_face_from_dom_inputs(LLVolumeFace& face, const domInputLocalOffset_Arr
|
|||
}
|
||||
}
|
||||
|
||||
void get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S32& tc_offset, S32& norm_offset, S32 &idx_stride,
|
||||
bool get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S32& tc_offset, S32& norm_offset, S32 &idx_stride,
|
||||
domSource* &pos_source, domSource* &tc_source, domSource* &norm_source)
|
||||
{
|
||||
|
||||
idx_stride = 0;
|
||||
|
||||
for (U32 j = 0; j < inputs.getCount(); ++j)
|
||||
|
|
@ -163,7 +164,11 @@ void get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S
|
|||
const domURIFragmentType& uri = inputs[j]->getSource();
|
||||
daeElementRef elem = uri.getElement();
|
||||
domVertices* vertices = (domVertices*) elem.cast();
|
||||
|
||||
if ( !vertices )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
domInputLocal_Array& v_inp = vertices->getInput_array();
|
||||
|
||||
|
||||
|
|
@ -207,6 +212,8 @@ void get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S
|
|||
}
|
||||
|
||||
idx_stride += 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& face_list, std::vector<std::string>& materials, domTrianglesRef& tri)
|
||||
|
|
@ -227,8 +234,12 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
|
|||
|
||||
S32 idx_stride = 0;
|
||||
|
||||
get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source);
|
||||
if ( !get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source) || !pos_source )
|
||||
{
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
|
||||
|
||||
domPRef p = tri->getP();
|
||||
domListOfUInts& idx = p->getValue();
|
||||
|
||||
|
|
@ -367,7 +378,10 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
|
|||
|
||||
S32 idx_stride = 0;
|
||||
|
||||
get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source);
|
||||
if (!get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source))
|
||||
{
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
|
||||
LLVolumeFace face;
|
||||
|
||||
|
|
@ -564,7 +578,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
|
|||
const domURIFragmentType& uri = inputs[i]->getSource();
|
||||
daeElementRef elem = uri.getElement();
|
||||
domVertices* vertices = (domVertices*) elem.cast();
|
||||
|
||||
if (!vertices)
|
||||
{
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
domInputLocal_Array& v_inp = vertices->getInput_array();
|
||||
|
||||
for (U32 k = 0; k < v_inp.getCount(); ++k)
|
||||
|
|
@ -574,6 +591,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
|
|||
const domURIFragmentType& uri = v_inp[k]->getSource();
|
||||
daeElementRef elem = uri.getElement();
|
||||
domSource* src = (domSource*) elem.cast();
|
||||
if (!src)
|
||||
{
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
v = &(src->getFloat_array()->getValue());
|
||||
}
|
||||
}
|
||||
|
|
@ -585,6 +606,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
|
|||
const domURIFragmentType& uri = inputs[i]->getSource();
|
||||
daeElementRef elem = uri.getElement();
|
||||
domSource* src = (domSource*) elem.cast();
|
||||
if (!src)
|
||||
{
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
n = &(src->getFloat_array()->getValue());
|
||||
}
|
||||
else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[i]->getSemantic()) == 0 && inputs[i]->getSet() == 0)
|
||||
|
|
@ -593,6 +618,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
|
|||
const domURIFragmentType& uri = inputs[i]->getSource();
|
||||
daeElementRef elem = uri.getElement();
|
||||
domSource* src = (domSource*) elem.cast();
|
||||
if (!src)
|
||||
{
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
t = &(src->getFloat_array()->getValue());
|
||||
}
|
||||
}
|
||||
|
|
@ -667,11 +696,6 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
|
|||
}
|
||||
}
|
||||
|
||||
if (cur_idx != vert_idx.size())
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
}
|
||||
|
||||
//build vertex array from map
|
||||
std::vector<LLVolumeFace::VertexData> new_verts;
|
||||
new_verts.resize(vert_idx.size());
|
||||
|
|
@ -717,7 +741,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
|
|||
//static
|
||||
std::string LLModel::getStatusString(U32 status)
|
||||
{
|
||||
const static std::string status_strings[(S32)INVALID_STATUS] = {"status_no_error", "status_vertex_number_overflow"};
|
||||
const static std::string status_strings[(S32)INVALID_STATUS] = {"status_no_error", "status_vertex_number_overflow","bad_element"};
|
||||
|
||||
if(status < INVALID_STATUS)
|
||||
{
|
||||
|
|
@ -755,7 +779,6 @@ void LLModel::addVolumeFacesFromDomMesh(domMesh* mesh)
|
|||
for (U32 i = 0; i < polys.getCount(); ++i)
|
||||
{
|
||||
domPolylistRef& poly = polys.get(i);
|
||||
|
||||
mStatus = load_face_from_dom_polylist(mVolumeFaces, mMaterialList, poly);
|
||||
|
||||
if(mStatus != NO_ERRORS)
|
||||
|
|
@ -765,12 +788,12 @@ void LLModel::addVolumeFacesFromDomMesh(domMesh* mesh)
|
|||
return ; //abort
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
domPolygons_Array& polygons = mesh->getPolygons_array();
|
||||
|
||||
for (U32 i = 0; i < polygons.getCount(); ++i)
|
||||
{
|
||||
domPolygonsRef& poly = polygons.get(i);
|
||||
|
||||
mStatus = load_face_from_dom_polygons(mVolumeFaces, mMaterialList, poly);
|
||||
|
||||
if(mStatus != NO_ERRORS)
|
||||
|
|
@ -780,7 +803,7 @@ void LLModel::addVolumeFacesFromDomMesh(domMesh* mesh)
|
|||
return ; //abort
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
BOOL LLModel::createVolumeFacesFromDomMesh(domMesh* mesh)
|
||||
|
|
@ -926,11 +949,6 @@ void LLModel::normalizeVolumeFaces()
|
|||
{
|
||||
LLVector4a min, max;
|
||||
|
||||
if (mVolumeFaces[0].mNumVertices <= 0)
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
}
|
||||
|
||||
// For all of the volume faces
|
||||
// in the model, loop over
|
||||
// them and see what the extents
|
||||
|
|
@ -942,11 +960,6 @@ void LLModel::normalizeVolumeFaces()
|
|||
{
|
||||
LLVolumeFace& face = mVolumeFaces[i];
|
||||
|
||||
if (face.mNumVertices <= 0)
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
}
|
||||
|
||||
update_min_max(min, max, face.mExtents[0]);
|
||||
update_min_max(min, max, face.mExtents[1]);
|
||||
}
|
||||
|
|
@ -1289,11 +1302,6 @@ void LLModel::generateNormals(F32 angle_cutoff)
|
|||
{
|
||||
LLVector4a& n = iter->second[k].getNormal();
|
||||
|
||||
if (!iter->second[k].getPosition().equals3(new_face.mPositions[i]))
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
}
|
||||
|
||||
F32 cur = n.dot3(ref_norm).getF32();
|
||||
|
||||
if (cur > best)
|
||||
|
|
@ -1410,7 +1418,11 @@ LLSD LLModel::writeModel(
|
|||
if (!decomp.mBaseHull.empty() ||
|
||||
!decomp.mHull.empty())
|
||||
{
|
||||
mdl["decomposition"] = decomp.asLLSD();
|
||||
mdl["physics_convex"] = decomp.asLLSD();
|
||||
if (!decomp.mHull.empty())
|
||||
{ //convex decomposition exists, physics mesh will not be used
|
||||
model[LLModel::LOD_PHYSICS] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (U32 idx = 0; idx < MODEL_NAMES_LENGTH; ++idx)
|
||||
|
|
@ -1435,8 +1447,9 @@ LLSD LLModel::writeModel(
|
|||
for (S32 i = 0; i < model[idx]->getNumVolumeFaces(); ++i)
|
||||
{ //for each face
|
||||
const LLVolumeFace& face = model[idx]->getVolumeFace(i);
|
||||
if (!face.mNumVertices)
|
||||
if (face.mNumVertices < 3)
|
||||
{ //don't export an empty face
|
||||
mdl[model_names[idx]][i]["NoGeometry"] = true;
|
||||
continue;
|
||||
}
|
||||
LLSD::Binary verts(face.mNumVertices*3*2);
|
||||
|
|
@ -1469,7 +1482,6 @@ LLSD LLModel::writeModel(
|
|||
//position + normal
|
||||
for (U32 k = 0; k < 3; ++k)
|
||||
{ //for each component
|
||||
|
||||
//convert to 16-bit normalized across domain
|
||||
U16 val = (U16) (((pos[k]-min_pos.mV[k])/pos_range.mV[k])*65535);
|
||||
|
||||
|
|
@ -1513,7 +1525,6 @@ LLSD LLModel::writeModel(
|
|||
//write out face data
|
||||
mdl[model_names[idx]][i]["PositionDomain"]["Min"] = min_pos.getValue();
|
||||
mdl[model_names[idx]][i]["PositionDomain"]["Max"] = max_pos.getValue();
|
||||
|
||||
mdl[model_names[idx]][i]["TexCoord0Domain"]["Min"] = min_tc.getValue();
|
||||
mdl[model_names[idx]][i]["TexCoord0Domain"]["Max"] = max_tc.getValue();
|
||||
|
||||
|
|
@ -1539,11 +1550,6 @@ LLSD LLModel::writeModel(
|
|||
|
||||
weight_list& weights = high->getJointInfluences(pos);
|
||||
|
||||
if (weights.size() > 4)
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
}
|
||||
|
||||
S32 count = 0;
|
||||
for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter)
|
||||
{
|
||||
|
|
@ -1607,23 +1613,19 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite)
|
|||
cur_offset += size;
|
||||
bytes += size;
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
std::string decomposition;
|
||||
|
||||
if (mdl.has("decomposition"))
|
||||
if (mdl.has("physics_convex"))
|
||||
{ //write out convex decomposition
|
||||
decomposition = zip_llsd(mdl["decomposition"]);
|
||||
decomposition = zip_llsd(mdl["physics_convex"]);
|
||||
|
||||
U32 size = decomposition.size();
|
||||
if (size > 0)
|
||||
{
|
||||
header["decomposition"]["offset"] = (LLSD::Integer) cur_offset;
|
||||
header["decomposition"]["size"] = (LLSD::Integer) size;
|
||||
header["physics_convex"]["offset"] = (LLSD::Integer) cur_offset;
|
||||
header["physics_convex"]["size"] = (LLSD::Integer) size;
|
||||
cur_offset += size;
|
||||
bytes += size;
|
||||
}
|
||||
|
|
@ -1644,11 +1646,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite)
|
|||
cur_offset += size;
|
||||
bytes += size;
|
||||
}
|
||||
else
|
||||
{
|
||||
header[model_names[i]]["offset"] = -1;
|
||||
header[model_names[i]]["size"] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!nowrite)
|
||||
|
|
@ -1662,7 +1659,7 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite)
|
|||
|
||||
if (!decomposition.empty())
|
||||
{ //write decomposition block
|
||||
ostr.write((const char*) decomposition.data(), header["decomposition"]["size"].asInteger());
|
||||
ostr.write((const char*) decomposition.data(), header["physics_convex"]["size"].asInteger());
|
||||
}
|
||||
|
||||
for (S32 i = 0; i < MODEL_NAMES_LENGTH; i++)
|
||||
|
|
@ -1685,7 +1682,7 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)
|
|||
{
|
||||
if ((iter->first - pos).magVec() > 0.1f)
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
llerrs << "Couldn't find weight list." << llendl;
|
||||
}
|
||||
|
||||
return iter->second;
|
||||
|
|
@ -1778,7 +1775,7 @@ void LLModel::updateHullCenters()
|
|||
if (mHullPoints > 0)
|
||||
{
|
||||
mCenterOfHullCenters *= 1.f / mHullPoints;
|
||||
llassert(mPhysics.asLLSD().has("HullList"));
|
||||
llassert(mPhysics.hasHullList());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1801,7 +1798,7 @@ bool LLModel::loadModel(std::istream& is)
|
|||
"low_lod",
|
||||
"medium_lod",
|
||||
"high_lod",
|
||||
"physics_shape",
|
||||
"physics_mesh",
|
||||
};
|
||||
|
||||
const S32 MODEL_LODS = 5;
|
||||
|
|
@ -1900,8 +1897,8 @@ bool LLModel::loadSkinInfo(LLSD& header, std::istream &is)
|
|||
|
||||
bool LLModel::loadDecomposition(LLSD& header, std::istream& is)
|
||||
{
|
||||
S32 offset = header["decomposition"]["offset"].asInteger();
|
||||
S32 size = header["decomposition"]["size"].asInteger();
|
||||
S32 offset = header["physics_convex"]["offset"].asInteger();
|
||||
S32 size = header["physics_convex"]["size"].asInteger();
|
||||
|
||||
if (offset >= 0 && size > 0)
|
||||
{
|
||||
|
|
@ -2041,7 +2038,7 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
|
|||
{
|
||||
// updated for const-correctness. gcc is picky about this type of thing - Nyx
|
||||
const LLSD::Binary& hulls = decomp["HullList"].asBinary();
|
||||
const LLSD::Binary& position = decomp["Position"].asBinary();
|
||||
const LLSD::Binary& position = decomp["Positions"].asBinary();
|
||||
|
||||
U16* p = (U16*) &position[0];
|
||||
|
||||
|
|
@ -2051,11 +2048,19 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
|
|||
LLVector3 max;
|
||||
LLVector3 range;
|
||||
|
||||
min.setValue(decomp["Min"]);
|
||||
max.setValue(decomp["Max"]);
|
||||
if (decomp.has("Min"))
|
||||
{
|
||||
min.setValue(decomp["Min"]);
|
||||
max.setValue(decomp["Max"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
min.set(-0.5f, -0.5f, -0.5f);
|
||||
max.set(0.5f, 0.5f, 0.5f);
|
||||
}
|
||||
|
||||
range = max-min;
|
||||
|
||||
|
||||
for (U32 i = 0; i < hulls.size(); ++i)
|
||||
{
|
||||
U16 count = (hulls[i] == 0) ? 256 : hulls[i];
|
||||
|
|
@ -2071,6 +2076,7 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
|
|||
//point must be unique
|
||||
//llassert(valid.find(test) == valid.end());
|
||||
valid.insert(test);
|
||||
|
||||
mHull[i].push_back(LLVector3(
|
||||
(F32) p[0]/65535.f*range.mV[0]+min.mV[0],
|
||||
(F32) p[1]/65535.f*range.mV[1]+min.mV[1],
|
||||
|
|
@ -2085,9 +2091,9 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
|
|||
}
|
||||
}
|
||||
|
||||
if (decomp.has("Hull"))
|
||||
if (decomp.has("BoundingVerts"))
|
||||
{
|
||||
const LLSD::Binary& position = decomp["Hull"].asBinary();
|
||||
const LLSD::Binary& position = decomp["BoundingVerts"].asBinary();
|
||||
|
||||
U16* p = (U16*) &position[0];
|
||||
|
||||
|
|
@ -2123,10 +2129,15 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
|
|||
{
|
||||
//empty base hull mesh to indicate decomposition has been loaded
|
||||
//but contains no base hull
|
||||
mBaseHullMesh.clear();;
|
||||
mBaseHullMesh.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool LLModel::Decomposition::hasHullList() const
|
||||
{
|
||||
return !mHull.empty() ;
|
||||
}
|
||||
|
||||
LLSD LLModel::Decomposition::asLLSD() const
|
||||
{
|
||||
LLSD ret;
|
||||
|
|
@ -2137,11 +2148,9 @@ LLSD LLModel::Decomposition::asLLSD() const
|
|||
}
|
||||
|
||||
//write decomposition block
|
||||
// ["decomposition"]["HullList"] -- list of 8 bit integers, each entry represents a hull with specified number of points
|
||||
// ["decomposition"]["PositionDomain"]["Min"/"Max"]
|
||||
// ["decomposition"]["Position"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points
|
||||
// ["decomposition"]["Hull"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points representing a single hull approximation of given shape
|
||||
|
||||
// ["physics_convex"]["HullList"] -- list of 8 bit integers, each entry represents a hull with specified number of points
|
||||
// ["physics_convex"]["Position"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points
|
||||
// ["physics_convex"]["BoundingVerts"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points representing a single hull approximation of given shape
|
||||
|
||||
//get minimum and maximum
|
||||
LLVector3 min;
|
||||
|
|
@ -2190,6 +2199,8 @@ LLSD LLModel::Decomposition::asLLSD() const
|
|||
{
|
||||
LLSD::Binary p(total*3*2);
|
||||
|
||||
LLVector3 min(-0.5f, -0.5f, -0.5f);
|
||||
LLVector3 max(0.5f, 0.5f, 0.5f);
|
||||
LLVector3 range = max-min;
|
||||
|
||||
U32 vert_idx = 0;
|
||||
|
|
@ -2205,17 +2216,24 @@ LLSD LLModel::Decomposition::asLLSD() const
|
|||
U64 test = 0;
|
||||
for (U32 k = 0; k < 3; k++)
|
||||
{
|
||||
F32* src = (F32*) (mHull[i][j].mV);
|
||||
|
||||
llassert(src[k] <= 0.501f && src[k] >= -0.501f);
|
||||
|
||||
//convert to 16-bit normalized across domain
|
||||
U16 val = (U16) (((mHull[i][j].mV[k]-min.mV[k])/range.mV[k])*65535);
|
||||
U16 val = (U16) (((src[k]-min.mV[k])/range.mV[k])*65535);
|
||||
|
||||
switch (k)
|
||||
if(valid.size() < 3)
|
||||
{
|
||||
case 0: test = test | (U64) val; break;
|
||||
case 1: test = test | ((U64) val << 16); break;
|
||||
case 2: test = test | ((U64) val << 32); break;
|
||||
};
|
||||
switch (k)
|
||||
{
|
||||
case 0: test = test | (U64) val; break;
|
||||
case 1: test = test | ((U64) val << 16); break;
|
||||
case 2: test = test | ((U64) val << 32); break;
|
||||
};
|
||||
|
||||
valid.insert(test);
|
||||
valid.insert(test);
|
||||
}
|
||||
|
||||
U8* buff = (U8*) &val;
|
||||
//write to binary buffer
|
||||
|
|
@ -2227,17 +2245,21 @@ LLSD LLModel::Decomposition::asLLSD() const
|
|||
}
|
||||
}
|
||||
|
||||
//must have at least 4 unique points
|
||||
llassert(valid.size() > 3);
|
||||
//must have at least 3 unique points
|
||||
llassert(valid.size() > 2);
|
||||
}
|
||||
|
||||
ret["Position"] = p;
|
||||
ret["Positions"] = p;
|
||||
}
|
||||
|
||||
//llassert(!mBaseHull.empty());
|
||||
|
||||
if (!mBaseHull.empty())
|
||||
{
|
||||
LLSD::Binary p(mBaseHull.size()*3*2);
|
||||
|
||||
LLVector3 min(-0.5f, -0.5f, -0.5f);
|
||||
LLVector3 max(0.5f, 0.5f, 0.5f);
|
||||
LLVector3 range = max-min;
|
||||
|
||||
U32 vert_idx = 0;
|
||||
|
|
@ -2245,6 +2267,8 @@ LLSD LLModel::Decomposition::asLLSD() const
|
|||
{
|
||||
for (U32 k = 0; k < 3; k++)
|
||||
{
|
||||
llassert(mBaseHull[j].mV[k] <= 0.51f && mBaseHull[j].mV[k] >= -0.51f);
|
||||
|
||||
//convert to 16-bit normalized across domain
|
||||
U16 val = (U16) (((mBaseHull[j].mV[k]-min.mV[k])/range.mV[k])*65535);
|
||||
|
||||
|
|
@ -2255,12 +2279,12 @@ LLSD LLModel::Decomposition::asLLSD() const
|
|||
|
||||
if (vert_idx > p.size())
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
llerrs << "Index out of bounds" << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret["Hull"] = p;
|
||||
ret["BoundingVerts"] = p;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -2290,10 +2314,5 @@ void LLModel::Decomposition::merge(const LLModel::Decomposition* rhs)
|
|||
{ //take physics shape mesh from rhs
|
||||
mPhysicsShapeMesh = rhs->mPhysicsShapeMesh;
|
||||
}
|
||||
|
||||
if (!mHull.empty())
|
||||
{ //verify
|
||||
llassert(asLLSD().has("HullList"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ public:
|
|||
{
|
||||
NO_ERRORS = 0,
|
||||
VERTEX_NUMBER_OVERFLOW, //vertex number is >= 65535.
|
||||
BAD_ELEMENT,
|
||||
INVALID_STATUS
|
||||
} ;
|
||||
|
||||
|
|
@ -106,6 +107,7 @@ public:
|
|||
Decomposition(LLSD& data);
|
||||
void fromLLSD(LLSD& data);
|
||||
LLSD asLLSD() const;
|
||||
bool hasHullList() const;
|
||||
|
||||
void merge(const Decomposition* rhs);
|
||||
|
||||
|
|
|
|||
|
|
@ -127,6 +127,11 @@ PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = NULL;
|
|||
PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB = NULL;
|
||||
PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB = NULL;
|
||||
|
||||
// GL_ARB_map_buffer_range
|
||||
PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
|
||||
PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange;
|
||||
|
||||
|
||||
// vertex object prototypes
|
||||
PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI = NULL;
|
||||
PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI = NULL;
|
||||
|
|
@ -178,6 +183,12 @@ PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer = NULL;
|
|||
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample = NULL;
|
||||
PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer = NULL;
|
||||
|
||||
//GL_ARB_texture_multisample
|
||||
PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
|
||||
PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
|
||||
PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
|
||||
PFNGLSAMPLEMASKIPROC glSampleMaski;
|
||||
|
||||
// GL_EXT_blend_func_separate
|
||||
PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT = NULL;
|
||||
|
||||
|
|
@ -321,9 +332,11 @@ LLGLManager::LLGLManager() :
|
|||
mHasMipMapGeneration(FALSE),
|
||||
mHasCompressedTextures(FALSE),
|
||||
mHasFramebufferObject(FALSE),
|
||||
mMaxSamples(0),
|
||||
mHasBlendFuncSeparate(FALSE),
|
||||
|
||||
mHasVertexBufferObject(FALSE),
|
||||
mHasMapBufferRange(FALSE),
|
||||
mHasPBuffer(FALSE),
|
||||
mHasShaderObjects(FALSE),
|
||||
mHasVertexShader(FALSE),
|
||||
|
|
@ -334,6 +347,11 @@ LLGLManager::LLGLManager() :
|
|||
mHasPointParameters(FALSE),
|
||||
mHasDrawBuffers(FALSE),
|
||||
mHasTextureRectangle(FALSE),
|
||||
mHasTextureMultisample(FALSE),
|
||||
mMaxSampleMaskWords(0),
|
||||
mMaxColorTextureSamples(0),
|
||||
mMaxDepthTextureSamples(0),
|
||||
mMaxIntegerSamples(0),
|
||||
|
||||
mHasAnisotropic(FALSE),
|
||||
mHasARBEnvCombine(FALSE),
|
||||
|
|
@ -539,7 +557,20 @@ bool LLGLManager::initGL()
|
|||
{
|
||||
GLint num_tex_image_units;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
|
||||
mNumTextureImageUnits = num_tex_image_units;
|
||||
mNumTextureImageUnits = llmin(num_tex_image_units, 32);
|
||||
}
|
||||
|
||||
if (mHasTextureMultisample)
|
||||
{
|
||||
glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &mMaxColorTextureSamples);
|
||||
glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &mMaxDepthTextureSamples);
|
||||
glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples);
|
||||
glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords);
|
||||
}
|
||||
|
||||
if (mHasFramebufferObject)
|
||||
{
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples);
|
||||
}
|
||||
|
||||
setToDebugGPU();
|
||||
|
|
@ -648,6 +679,14 @@ std::string LLGLManager::getRawGLString()
|
|||
return gl_string;
|
||||
}
|
||||
|
||||
U32 LLGLManager::getNumFBOFSAASamples(U32 samples)
|
||||
{
|
||||
samples = llmin(samples, (U32) mMaxColorTextureSamples);
|
||||
samples = llmin(samples, (U32) mMaxDepthTextureSamples);
|
||||
samples = llmin(samples, (U32) 4);
|
||||
return samples;
|
||||
}
|
||||
|
||||
void LLGLManager::shutdownGL()
|
||||
{
|
||||
if (mInited)
|
||||
|
|
@ -728,6 +767,7 @@ void LLGLManager::initExtensions()
|
|||
mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);
|
||||
mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts);
|
||||
mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
|
||||
mHasMapBufferRange = ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts);
|
||||
mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
|
||||
// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad
|
||||
#ifdef GL_ARB_framebuffer_object
|
||||
|
|
@ -742,6 +782,7 @@ void LLGLManager::initExtensions()
|
|||
mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts);
|
||||
mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts);
|
||||
mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts);
|
||||
mHasTextureMultisample = ExtensionExists("GL_ARB_texture_multisample", gGLHExts.mSysExts);
|
||||
#if !LL_DARWIN
|
||||
mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
|
||||
#endif
|
||||
|
|
@ -921,6 +962,11 @@ void LLGLManager::initExtensions()
|
|||
mHasVertexBufferObject = FALSE;
|
||||
}
|
||||
}
|
||||
if (mHasMapBufferRange)
|
||||
{
|
||||
glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glMapBufferRange");
|
||||
glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glFlushMappedBufferRange");
|
||||
}
|
||||
if (mHasFramebufferObject)
|
||||
{
|
||||
llinfos << "initExtensions() FramebufferObject-related procs..." << llendl;
|
||||
|
|
@ -953,6 +999,13 @@ void LLGLManager::initExtensions()
|
|||
{
|
||||
glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBlendFuncSeparateEXT");
|
||||
}
|
||||
if (mHasTextureMultisample)
|
||||
{
|
||||
glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage2DMultisample");
|
||||
glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage3DMultisample");
|
||||
glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetMultisamplefv");
|
||||
glSampleMaski = (PFNGLSAMPLEMASKIPROC) GLH_EXT_GET_PROC_ADDRESS("glSampleMaski");
|
||||
}
|
||||
#if (!LL_LINUX && !LL_SOLARIS) || LL_LINUX_NV_GL_HEADERS
|
||||
// This is expected to be a static symbol on Linux GL implementations, except if we use the nvidia headers - bah
|
||||
glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
|
||||
|
|
@ -1370,10 +1423,6 @@ void LLGLState::checkTextureChannels(const std::string& msg)
|
|||
}
|
||||
}
|
||||
|
||||
GLint maxTextureUnits = 0;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits);
|
||||
stop_glerror();
|
||||
|
||||
static const char* label[] =
|
||||
{
|
||||
"GL_TEXTURE_2D",
|
||||
|
|
@ -1384,7 +1433,8 @@ void LLGLState::checkTextureChannels(const std::string& msg)
|
|||
"GL_TEXTURE_GEN_T",
|
||||
"GL_TEXTURE_GEN_Q",
|
||||
"GL_TEXTURE_GEN_R",
|
||||
"GL_TEXTURE_RECTANGLE_ARB"
|
||||
"GL_TEXTURE_RECTANGLE_ARB",
|
||||
"GL_TEXTURE_2D_MULTISAMPLE"
|
||||
};
|
||||
|
||||
static GLint value[] =
|
||||
|
|
@ -1397,7 +1447,8 @@ void LLGLState::checkTextureChannels(const std::string& msg)
|
|||
GL_TEXTURE_GEN_T,
|
||||
GL_TEXTURE_GEN_Q,
|
||||
GL_TEXTURE_GEN_R,
|
||||
GL_TEXTURE_RECTANGLE_ARB
|
||||
GL_TEXTURE_RECTANGLE_ARB,
|
||||
GL_TEXTURE_2D_MULTISAMPLE
|
||||
};
|
||||
|
||||
GLint stackDepth = 0;
|
||||
|
|
@ -1406,68 +1457,96 @@ void LLGLState::checkTextureChannels(const std::string& msg)
|
|||
glh::matrix4f identity;
|
||||
identity.identity();
|
||||
|
||||
for (GLint i = 1; i < maxTextureUnits; i++)
|
||||
for (GLint i = 1; i < gGLManager.mNumTextureUnits; i++)
|
||||
{
|
||||
gGL.getTexUnit(i)->activate();
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB+i);
|
||||
stop_glerror();
|
||||
glGetIntegerv(GL_TEXTURE_STACK_DEPTH, &stackDepth);
|
||||
stop_glerror();
|
||||
|
||||
if (stackDepth != 1)
|
||||
if (i < gGLManager.mNumTextureUnits)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "Texture matrix stack corrupted." << LL_ENDL;
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB+i);
|
||||
stop_glerror();
|
||||
glGetIntegerv(GL_TEXTURE_STACK_DEPTH, &stackDepth);
|
||||
stop_glerror();
|
||||
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Texture matrix stack corrupted." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) mat.m);
|
||||
stop_glerror();
|
||||
|
||||
if (mat != identity)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "Texture matrix in channel " << i << " corrupt." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Texture matrix in channel " << i << " corrupt." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (S32 j = (i == 0 ? 1 : 0);
|
||||
j < (gGLManager.mHasTextureRectangle ? 9 : 8); j++)
|
||||
{
|
||||
if (glIsEnabled(value[j]))
|
||||
if (stackDepth != 1)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "Texture channel " << i << " still has " << label[j] << " enabled." << LL_ENDL;
|
||||
LL_WARNS("RenderState") << "Texture matrix stack corrupted." << LL_ENDL;
|
||||
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Texture channel " << i << " still has " << label[j] << " enabled." << std::endl;
|
||||
gFailLog << "Texture matrix stack corrupted." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) mat.m);
|
||||
stop_glerror();
|
||||
|
||||
if (mat != identity)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "Texture matrix in channel " << i << " corrupt." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Texture matrix in channel " << i << " corrupt." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
for (S32 j = (i == 0 ? 1 : 0);
|
||||
j < 9; j++)
|
||||
{
|
||||
if (j == 8 && !gGLManager.mHasTextureRectangle ||
|
||||
j == 9 && !gGLManager.mHasTextureMultisample)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (glIsEnabled(value[j]))
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "Texture channel " << i << " still has " << label[j] << " enabled." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Texture channel " << i << " still has " << label[j] << " enabled." << std::endl;
|
||||
}
|
||||
}
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
glGetFloatv(GL_TEXTURE_MATRIX, mat.m);
|
||||
stop_glerror();
|
||||
|
||||
if (mat != identity)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "Texture matrix " << i << " is not identity." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Texture matrix " << i << " is not identity." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glGetFloatv(GL_TEXTURE_MATRIX, mat.m);
|
||||
stop_glerror();
|
||||
|
||||
if (mat != identity)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "Texture matrix " << i << " is not identity." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
GLint tex = 0;
|
||||
stop_glerror();
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex);
|
||||
stop_glerror();
|
||||
|
||||
if (tex != 0)
|
||||
{
|
||||
gFailLog << "Texture matrix " << i << " is not identity." << std::endl;
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "Texture channel " << i << " still has texture " << tex << " bound." << llendl;
|
||||
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Texture channel " << i << " still has texture " << tex << " bound." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
gGL.getTexUnit(0)->activate();
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
stop_glerror();
|
||||
|
|
|
|||
|
|
@ -83,10 +83,12 @@ public:
|
|||
BOOL mHasMipMapGeneration;
|
||||
BOOL mHasCompressedTextures;
|
||||
BOOL mHasFramebufferObject;
|
||||
S32 mMaxSamples;
|
||||
BOOL mHasBlendFuncSeparate;
|
||||
|
||||
|
||||
// ARB Extensions
|
||||
BOOL mHasVertexBufferObject;
|
||||
BOOL mHasMapBufferRange;
|
||||
BOOL mHasPBuffer;
|
||||
BOOL mHasShaderObjects;
|
||||
BOOL mHasVertexShader;
|
||||
|
|
@ -98,6 +100,11 @@ public:
|
|||
BOOL mHasDrawBuffers;
|
||||
BOOL mHasDepthClamp;
|
||||
BOOL mHasTextureRectangle;
|
||||
BOOL mHasTextureMultisample;
|
||||
S32 mMaxSampleMaskWords;
|
||||
S32 mMaxColorTextureSamples;
|
||||
S32 mMaxDepthTextureSamples;
|
||||
S32 mMaxIntegerSamples;
|
||||
|
||||
// Other extensions.
|
||||
BOOL mHasAnisotropic;
|
||||
|
|
@ -139,6 +146,7 @@ public:
|
|||
void printGLInfoString();
|
||||
void getGLInfo(LLSD& info);
|
||||
|
||||
U32 getNumFBOFSAASamples(U32 desired_samples = 32);
|
||||
// In ALL CAPS
|
||||
std::string mGLVendor;
|
||||
std::string mGLVendorShort;
|
||||
|
|
|
|||
|
|
@ -68,6 +68,10 @@ extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB;
|
|||
extern PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB;
|
||||
extern PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB;
|
||||
|
||||
// GL_ARB_map_buffer_range
|
||||
extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
|
||||
extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange;
|
||||
|
||||
// GL_ATI_vertex_array_object
|
||||
extern PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI;
|
||||
extern PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI;
|
||||
|
|
@ -306,6 +310,10 @@ extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB;
|
|||
extern PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB;
|
||||
extern PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB;
|
||||
|
||||
// GL_ARB_map_buffer_range
|
||||
extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
|
||||
extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange;
|
||||
|
||||
// GL_ATI_vertex_array_object
|
||||
extern PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI;
|
||||
extern PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI;
|
||||
|
|
@ -474,6 +482,11 @@ extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer;
|
|||
//GL_ARB_draw_buffers
|
||||
extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;
|
||||
|
||||
//GL_ARB_texture_multisample
|
||||
extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
|
||||
extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
|
||||
extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
|
||||
extern PFNGLSAMPLEMASKIPROC glSampleMaski;
|
||||
|
||||
#elif LL_WINDOWS
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
@ -506,6 +519,10 @@ extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB;
|
|||
extern PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB;
|
||||
extern PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB;
|
||||
|
||||
// GL_ARB_map_buffer_range
|
||||
extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
|
||||
extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange;
|
||||
|
||||
// GL_ATI_vertex_array_object
|
||||
extern PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI;
|
||||
extern PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI;
|
||||
|
|
@ -673,6 +690,11 @@ extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer;
|
|||
//GL_ARB_draw_buffers
|
||||
extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;
|
||||
|
||||
//GL_ARB_texture_multisample
|
||||
extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
|
||||
extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
|
||||
extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
|
||||
extern PFNGLSAMPLEMASKIPROC glSampleMaski;
|
||||
|
||||
#elif LL_DARWIN
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
@ -714,13 +736,55 @@ extern void glGenerateMipmapEXT(GLenum target) AVAILABLE_MAC_OS_X_VERSION_10_4_A
|
|||
|
||||
#ifndef GL_ARB_framebuffer_object
|
||||
#define glGenerateMipmap glGenerateMipmapEXT
|
||||
#define GL_MAX_SAMPLES 0x8D57
|
||||
#endif
|
||||
|
||||
// GL_ARB_draw_buffers
|
||||
extern void glDrawBuffersARB(GLsizei n, const GLenum* bufs) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//
|
||||
// Define map buffer range headers on Mac
|
||||
//
|
||||
#ifndef GL_ARB_map_buffer_range
|
||||
#define GL_MAP_READ_BIT 0x0001
|
||||
#define GL_MAP_WRITE_BIT 0x0002
|
||||
#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
|
||||
#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
|
||||
#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
|
||||
#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
|
||||
#endif
|
||||
|
||||
//
|
||||
// Define multisample headers on Mac
|
||||
//
|
||||
#ifndef GL_ARB_texture_multisample
|
||||
#define GL_SAMPLE_POSITION 0x8E50
|
||||
#define GL_SAMPLE_MASK 0x8E51
|
||||
#define GL_SAMPLE_MASK_VALUE 0x8E52
|
||||
#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
|
||||
#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
|
||||
#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101
|
||||
#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
|
||||
#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103
|
||||
#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
|
||||
#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105
|
||||
#define GL_TEXTURE_SAMPLES 0x9106
|
||||
#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
|
||||
#define GL_SAMPLER_2D_MULTISAMPLE 0x9108
|
||||
#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
|
||||
#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
|
||||
#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
|
||||
#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
|
||||
#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
|
||||
#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E
|
||||
#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F
|
||||
#define GL_MAX_INTEGER_SAMPLES 0x9110
|
||||
#endif
|
||||
|
||||
//
|
||||
// Define vertex buffer object headers on Mac
|
||||
//
|
||||
|
|
@ -757,7 +821,7 @@ extern "C" {
|
|||
#define GL_DYNAMIC_READ_ARB 0x88E9
|
||||
#define GL_DYNAMIC_COPY_ARB 0x88EA
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef GL_ARB_vertex_buffer_object
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ using std::pair;
|
|||
using std::make_pair;
|
||||
using std::string;
|
||||
|
||||
GLhandleARB LLGLSLShader::sCurBoundShader = 0;
|
||||
|
||||
BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
|
||||
{
|
||||
return v1 != v2;
|
||||
|
|
@ -56,7 +58,7 @@ BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
|
|||
LLShaderFeatures::LLShaderFeatures()
|
||||
: calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false),
|
||||
hasTransport(false), hasSkinning(false), hasObjectSkinning(false), hasAtmospherics(false), isSpecular(false),
|
||||
hasGamma(false), hasLighting(false), calculatesAtmospherics(false)
|
||||
hasGamma(false), hasLighting(false), calculatesAtmospherics(false), mIndexedTextureChannels(0), disableTextureIndex(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -107,16 +109,11 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
|
|||
// Create program
|
||||
mProgramObject = glCreateProgramObjectARB();
|
||||
|
||||
// Attach existing objects
|
||||
if (!LLShaderMgr::instance()->attachShaderFeatures(this))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//compile new source
|
||||
vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
|
||||
for ( ; fileIter != mShaderFiles.end(); fileIter++ )
|
||||
{
|
||||
GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second);
|
||||
GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, mFeatures.mIndexedTextureChannels);
|
||||
LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
|
||||
if (shaderhandle > 0)
|
||||
{
|
||||
|
|
@ -128,6 +125,12 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
|
|||
}
|
||||
}
|
||||
|
||||
// Attach existing objects
|
||||
if (!LLShaderMgr::instance()->attachShaderFeatures(this))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Map attributes and uniforms
|
||||
if (success)
|
||||
{
|
||||
|
|
@ -149,6 +152,29 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
|
|||
return createShader(attributes,uniforms);
|
||||
}
|
||||
}
|
||||
else if (mFeatures.mIndexedTextureChannels > 0)
|
||||
{ //override texture channels for indexed texture rendering
|
||||
bind();
|
||||
S32 channel_count = mFeatures.mIndexedTextureChannels;
|
||||
|
||||
for (S32 i = 0; i < channel_count; i++)
|
||||
{
|
||||
uniform1i(llformat("tex%d", i), i);
|
||||
}
|
||||
|
||||
S32 cur_tex = channel_count; //adjust any texture channels that might have been overwritten
|
||||
for (U32 i = 0; i < mTexture.size(); i++)
|
||||
{
|
||||
if (mTexture[i] > -1 && mTexture[i] < channel_count)
|
||||
{
|
||||
llassert(cur_tex < gGLManager.mNumTextureImageUnits);
|
||||
uniform1i(i, cur_tex);
|
||||
mTexture[i] = cur_tex++;
|
||||
}
|
||||
}
|
||||
unbind();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
|
@ -293,7 +319,8 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
|
|||
|
||||
GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
|
||||
{
|
||||
if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB)
|
||||
if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB ||
|
||||
type == GL_SAMPLER_2D_MULTISAMPLE)
|
||||
{ //this here is a texture
|
||||
glUniform1iARB(location, mActiveTextureChannels);
|
||||
LL_DEBUGS("ShaderLoading") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL;
|
||||
|
|
@ -342,7 +369,7 @@ void LLGLSLShader::bind()
|
|||
if (gGLManager.mHasShaderObjects)
|
||||
{
|
||||
glUseProgramObjectARB(mProgramObject);
|
||||
|
||||
sCurBoundShader = mProgramObject;
|
||||
if (mUniformsDirty)
|
||||
{
|
||||
LLShaderMgr::instance()->updateShaderUniforms(this);
|
||||
|
|
@ -365,6 +392,7 @@ void LLGLSLShader::unbind()
|
|||
}
|
||||
}
|
||||
glUseProgramObjectARB(0);
|
||||
sCurBoundShader = 0;
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
|
|
@ -372,6 +400,7 @@ void LLGLSLShader::unbind()
|
|||
void LLGLSLShader::bindNoShader(void)
|
||||
{
|
||||
glUseProgramObjectARB(0);
|
||||
sCurBoundShader = 0;
|
||||
}
|
||||
|
||||
S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ public:
|
|||
bool hasObjectSkinning;
|
||||
bool hasAtmospherics;
|
||||
bool hasGamma;
|
||||
S32 mIndexedTextureChannels;
|
||||
bool disableTextureIndex;
|
||||
|
||||
// char numLights;
|
||||
|
||||
|
|
@ -64,6 +66,8 @@ public:
|
|||
|
||||
LLGLSLShader();
|
||||
|
||||
static GLhandleARB sCurBoundShader;
|
||||
|
||||
void unload();
|
||||
BOOL createShader(std::vector<std::string> * attributes,
|
||||
std::vector<std::string> * uniforms);
|
||||
|
|
|
|||
|
|
@ -1083,12 +1083,17 @@ void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
|
|||
}
|
||||
|
||||
// static
|
||||
void LLImageGL::deleteTextures(S32 numTextures, U32 *textures)
|
||||
void LLImageGL::deleteTextures(S32 numTextures, U32 *textures, bool immediate)
|
||||
{
|
||||
for (S32 i = 0; i < numTextures; i++)
|
||||
{
|
||||
sDeadTextureList.push_back(textures[i]);
|
||||
}
|
||||
|
||||
if (immediate)
|
||||
{
|
||||
LLImageGL::deleteDeadTextures();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -1413,11 +1418,13 @@ void LLImageGL::deleteDeadTextures()
|
|||
{
|
||||
GLuint tex = sDeadTextureList.front();
|
||||
sDeadTextureList.pop_front();
|
||||
for (int i = 0; i < gGLManager.mNumTextureUnits; i++)
|
||||
for (int i = 0; i < gGLManager.mNumTextureImageUnits; i++)
|
||||
{
|
||||
if (sCurrentBoundTextures[i] == tex)
|
||||
LLTexUnit* tex_unit = gGL.getTexUnit(i);
|
||||
|
||||
if (tex_unit->getCurrTexture() == tex)
|
||||
{
|
||||
gGL.getTexUnit(i)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
tex_unit->unbind(tex_unit->getCurrType());
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ public:
|
|||
// These 3 functions currently wrap glGenTextures(), glDeleteTextures(), and glTexImage2D()
|
||||
// for tracking purposes and will be deprecated in the future
|
||||
static void generateTextures(S32 numTextures, U32 *textures);
|
||||
static void deleteTextures(S32 numTextures, U32 *textures);
|
||||
static void deleteTextures(S32 numTextures, U32 *textures, bool immediate = false);
|
||||
static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels);
|
||||
|
||||
BOOL createGLTexture() ;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "llvertexbuffer.h"
|
||||
#include "llcubemap.h"
|
||||
#include "llglslshader.h"
|
||||
#include "llimagegl.h"
|
||||
#include "llrendertarget.h"
|
||||
#include "lltexture.h"
|
||||
|
|
@ -46,14 +47,15 @@ S32 gGLViewport[4];
|
|||
U32 LLRender::sUICalls = 0;
|
||||
U32 LLRender::sUIVerts = 0;
|
||||
|
||||
static const U32 LL_NUM_TEXTURE_LAYERS = 16;
|
||||
static const U32 LL_NUM_TEXTURE_LAYERS = 32;
|
||||
static const U32 LL_NUM_LIGHT_UNITS = 8;
|
||||
|
||||
static GLenum sGLTextureType[] =
|
||||
{
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE_RECTANGLE_ARB,
|
||||
GL_TEXTURE_CUBE_MAP_ARB
|
||||
GL_TEXTURE_CUBE_MAP_ARB,
|
||||
GL_TEXTURE_2D_MULTISAMPLE
|
||||
};
|
||||
|
||||
static GLint sGLAddressMode[] =
|
||||
|
|
@ -124,7 +126,7 @@ void LLTexUnit::refreshState(void)
|
|||
// Per apple spec, don't call glEnable/glDisable when index exceeds max texture units
|
||||
// http://www.mailinglistarchive.com/html/mac-opengl@lists.apple.com/2008-07/msg00653.html
|
||||
//
|
||||
bool enableDisable = (mIndex < gGLManager.mNumTextureUnits);
|
||||
bool enableDisable = (mIndex < gGLManager.mNumTextureUnits) && mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE;
|
||||
|
||||
if (mCurrTexType != TT_NONE)
|
||||
{
|
||||
|
|
@ -182,8 +184,8 @@ void LLTexUnit::enable(eTextureType type)
|
|||
mCurrTexType = type;
|
||||
|
||||
gGL.flush();
|
||||
|
||||
if (mIndex < gGLManager.mNumTextureUnits)
|
||||
if (type != LLTexUnit::TT_MULTISAMPLE_TEXTURE &&
|
||||
mIndex < gGLManager.mNumTextureUnits)
|
||||
{
|
||||
glEnable(sGLTextureType[type]);
|
||||
}
|
||||
|
|
@ -199,8 +201,8 @@ void LLTexUnit::disable(void)
|
|||
activate();
|
||||
unbind(mCurrTexType);
|
||||
gGL.flush();
|
||||
|
||||
if (mIndex < gGLManager.mNumTextureUnits)
|
||||
if (mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE &&
|
||||
mIndex < gGLManager.mNumTextureUnits)
|
||||
{
|
||||
glDisable(sGLTextureType[mCurrTexType]);
|
||||
}
|
||||
|
|
@ -292,7 +294,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind)
|
|||
glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture);
|
||||
texture->updateBindStats(texture->mTextureMemory);
|
||||
mHasMipMaps = texture->mHasMipMaps;
|
||||
if (texture->mTexOptionsDirty)
|
||||
if (mIndex == 0 && texture->mTexOptionsDirty)
|
||||
{
|
||||
texture->mTexOptionsDirty = false;
|
||||
setTextureAddressMode(texture->mAddressMode);
|
||||
|
|
@ -402,6 +404,7 @@ void LLTexUnit::unbind(eTextureType type)
|
|||
activate();
|
||||
mCurrTexture = 0;
|
||||
glBindTexture(sGLTextureType[type], 0);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -423,7 +426,7 @@ void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode)
|
|||
|
||||
void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option)
|
||||
{
|
||||
if (mIndex < 0 || mCurrTexture == 0) return;
|
||||
if (mIndex < 0 || mCurrTexture == 0 || mCurrTexType == LLTexUnit::TT_MULTISAMPLE_TEXTURE) return;
|
||||
|
||||
gGL.flush();
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ public:
|
|||
TT_TEXTURE = 0, // Standard 2D Texture
|
||||
TT_RECT_TEXTURE, // Non power of 2 texture
|
||||
TT_CUBE_MAP, // 6-sided cube map texture
|
||||
TT_MULTISAMPLE_TEXTURE, // see GL_ARB_texture_multisample
|
||||
TT_NONE // No texture type is currently enabled
|
||||
} eTextureType;
|
||||
|
||||
|
|
|
|||
|
|
@ -63,8 +63,7 @@ LLRenderTarget::LLRenderTarget() :
|
|||
mUseDepth(false),
|
||||
mRenderDepth(false),
|
||||
mUsage(LLTexUnit::TT_TEXTURE),
|
||||
mSamples(0),
|
||||
mSampleBuffer(NULL)
|
||||
mSamples(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -73,23 +72,32 @@ LLRenderTarget::~LLRenderTarget()
|
|||
release();
|
||||
}
|
||||
|
||||
|
||||
void LLRenderTarget::setSampleBuffer(LLMultisampleBuffer* buffer)
|
||||
{
|
||||
mSampleBuffer = buffer;
|
||||
}
|
||||
|
||||
void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo)
|
||||
void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples)
|
||||
{
|
||||
stop_glerror();
|
||||
|
||||
release();
|
||||
|
||||
mResX = resx;
|
||||
mResY = resy;
|
||||
|
||||
mStencil = stencil;
|
||||
mUsage = usage;
|
||||
mUseDepth = depth;
|
||||
mSamples = samples;
|
||||
|
||||
release();
|
||||
mSamples = gGLManager.getNumFBOFSAASamples(mSamples);
|
||||
|
||||
if (mSamples > 1 && gGLManager.mHasTextureMultisample)
|
||||
{
|
||||
mUsage = LLTexUnit::TT_MULTISAMPLE_TEXTURE;
|
||||
//no support for multisampled stencil targets yet
|
||||
mStencil = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mSamples = 0;
|
||||
}
|
||||
|
||||
if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
|
||||
{
|
||||
|
|
@ -146,29 +154,51 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt)
|
|||
|
||||
stop_glerror();
|
||||
|
||||
LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
#ifdef GL_ARB_texture_multisample
|
||||
if (mSamples > 1)
|
||||
{
|
||||
glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, color_fmt, mResX, mResY, GL_TRUE);
|
||||
}
|
||||
else
|
||||
#else
|
||||
llassert_always(mSamples <= 1);
|
||||
#endif
|
||||
{
|
||||
LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
|
||||
if (offset == 0)
|
||||
{
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
|
||||
}
|
||||
else
|
||||
{ //don't filter data attachments
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
|
||||
}
|
||||
if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
|
||||
{
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ATI doesn't support mirrored repeat for rectangular textures.
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
if (mSamples == 0)
|
||||
{
|
||||
if (offset == 0)
|
||||
{ //use bilinear filtering on single texture render targets that aren't multisampled
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
{ //don't filter data attachments
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
|
||||
{
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR);
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
{
|
||||
// ATI doesn't support mirrored repeat for rectangular textures.
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
|
||||
if (mFBO)
|
||||
{
|
||||
stop_glerror();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset,
|
||||
LLTexUnit::getInternalType(mUsage), tex, 0);
|
||||
|
|
@ -181,6 +211,12 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt)
|
|||
|
||||
mTex.push_back(tex);
|
||||
|
||||
if (gDebugGL)
|
||||
{ //bind and unbind to validate target
|
||||
bindTarget();
|
||||
flush();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLRenderTarget::allocateDepth()
|
||||
|
|
@ -197,9 +233,20 @@ void LLRenderTarget::allocateDepth()
|
|||
{
|
||||
LLImageGL::generateTextures(1, &mDepth);
|
||||
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
|
||||
U32 internal_type = LLTexUnit::getInternalType(mUsage);
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
|
||||
LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT32, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
|
||||
if (mSamples == 0)
|
||||
{
|
||||
U32 internal_type = LLTexUnit::getInternalType(mUsage);
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
|
||||
LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT32, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
|
||||
}
|
||||
#ifdef GL_ARB_texture_multisample
|
||||
else
|
||||
{
|
||||
glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, GL_DEPTH_COMPONENT32, mResX, mResY, GL_TRUE);
|
||||
}
|
||||
#else
|
||||
llassert_always(mSamples <= 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -239,6 +286,9 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
|
|||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
check_framebuffer_status();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
target.mUseDepth = true;
|
||||
|
|
@ -256,7 +306,7 @@ void LLRenderTarget::release()
|
|||
}
|
||||
else
|
||||
{
|
||||
LLImageGL::deleteTextures(1, &mDepth);
|
||||
LLImageGL::deleteTextures(1, &mDepth, true);
|
||||
stop_glerror();
|
||||
}
|
||||
mDepth = 0;
|
||||
|
|
@ -285,11 +335,12 @@ void LLRenderTarget::release()
|
|||
|
||||
if (mTex.size() > 0)
|
||||
{
|
||||
LLImageGL::deleteTextures(mTex.size(), &mTex[0]);
|
||||
LLImageGL::deleteTextures(mTex.size(), &mTex[0], true);
|
||||
mTex.clear();
|
||||
}
|
||||
|
||||
mResX = mResY = 0;
|
||||
|
||||
mSampleBuffer = NULL;
|
||||
sBoundTarget = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -298,34 +349,27 @@ void LLRenderTarget::bindTarget()
|
|||
if (mFBO)
|
||||
{
|
||||
stop_glerror();
|
||||
if (mSampleBuffer)
|
||||
{
|
||||
mSampleBuffer->bindTarget(this);
|
||||
stop_glerror();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
stop_glerror();
|
||||
if (gGLManager.mHasDrawBuffers)
|
||||
{ //setup multiple render targets
|
||||
GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0,
|
||||
GL_COLOR_ATTACHMENT1,
|
||||
GL_COLOR_ATTACHMENT2,
|
||||
GL_COLOR_ATTACHMENT3};
|
||||
glDrawBuffersARB(mTex.size(), drawbuffers);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
stop_glerror();
|
||||
if (gGLManager.mHasDrawBuffers)
|
||||
{ //setup multiple render targets
|
||||
GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0,
|
||||
GL_COLOR_ATTACHMENT1,
|
||||
GL_COLOR_ATTACHMENT2,
|
||||
GL_COLOR_ATTACHMENT3};
|
||||
glDrawBuffersARB(mTex.size(), drawbuffers);
|
||||
}
|
||||
|
||||
if (mTex.empty())
|
||||
{ //no color buffer to draw to
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
}
|
||||
|
||||
check_framebuffer_status();
|
||||
|
||||
stop_glerror();
|
||||
if (mTex.empty())
|
||||
{ //no color buffer to draw to
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
}
|
||||
|
||||
check_framebuffer_status();
|
||||
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
glViewport(0, 0, mResX, mResY);
|
||||
|
|
@ -407,50 +451,8 @@ void LLRenderTarget::flush(bool fetch_depth)
|
|||
else
|
||||
{
|
||||
stop_glerror();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
stop_glerror();
|
||||
|
||||
if (mSampleBuffer)
|
||||
{
|
||||
LLGLEnable multisample(GL_MULTISAMPLE);
|
||||
stop_glerror();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
stop_glerror();
|
||||
check_framebuffer_status();
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, mSampleBuffer->mFBO);
|
||||
check_framebuffer_status();
|
||||
|
||||
stop_glerror();
|
||||
glBlitFramebuffer(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
|
||||
stop_glerror();
|
||||
|
||||
if (mTex.size() > 1)
|
||||
{
|
||||
for (U32 i = 1; i < mTex.size(); ++i)
|
||||
{
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
LLTexUnit::getInternalType(mUsage), mTex[i], 0);
|
||||
stop_glerror();
|
||||
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mSampleBuffer->mTex[i]);
|
||||
stop_glerror();
|
||||
glBlitFramebuffer(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < mTex.size(); ++i)
|
||||
{
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i,
|
||||
LLTexUnit::getInternalType(mUsage), mTex[i], 0);
|
||||
stop_glerror();
|
||||
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, GL_RENDERBUFFER, mSampleBuffer->mTex[i]);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -467,37 +469,36 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0,
|
|||
llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
|
||||
}
|
||||
|
||||
if (mSampleBuffer)
|
||||
|
||||
if (mask == GL_DEPTH_BUFFER_BIT && source.mStencil != mStencil)
|
||||
{
|
||||
mSampleBuffer->copyContents(source, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
|
||||
stop_glerror();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, source.mFBO);
|
||||
check_framebuffer_status();
|
||||
gGL.getTexUnit(0)->bind(this, true);
|
||||
stop_glerror();
|
||||
glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1);
|
||||
stop_glerror();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mask == GL_DEPTH_BUFFER_BIT && source.mStencil != mStencil)
|
||||
{
|
||||
stop_glerror();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, source.mFBO);
|
||||
gGL.getTexUnit(0)->bind(this, true);
|
||||
stop_glerror();
|
||||
glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1);
|
||||
stop_glerror();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, source.mFBO);
|
||||
stop_glerror();
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFBO);
|
||||
stop_glerror();
|
||||
check_framebuffer_status();
|
||||
stop_glerror();
|
||||
glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
|
||||
stop_glerror();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
stop_glerror();
|
||||
}
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, source.mFBO);
|
||||
stop_glerror();
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFBO);
|
||||
stop_glerror();
|
||||
check_framebuffer_status();
|
||||
stop_glerror();
|
||||
glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
|
||||
stop_glerror();
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
stop_glerror();
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
stop_glerror();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -540,179 +541,3 @@ void LLRenderTarget::getViewport(S32* viewport)
|
|||
viewport[3] = mResY;
|
||||
}
|
||||
|
||||
//==================================================
|
||||
// LLMultisampleBuffer implementation
|
||||
//==================================================
|
||||
LLMultisampleBuffer::LLMultisampleBuffer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
LLMultisampleBuffer::~LLMultisampleBuffer()
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::release()
|
||||
{
|
||||
if (mFBO)
|
||||
{
|
||||
glDeleteFramebuffers(1, (GLuint *) &mFBO);
|
||||
mFBO = 0;
|
||||
}
|
||||
|
||||
if (mTex.size() > 0)
|
||||
{
|
||||
glDeleteRenderbuffers(mTex.size(), (GLuint *) &mTex[0]);
|
||||
mTex.clear();
|
||||
}
|
||||
|
||||
if (mDepth)
|
||||
{
|
||||
glDeleteRenderbuffers(1, (GLuint *) &mDepth);
|
||||
mDepth = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::bindTarget()
|
||||
{
|
||||
bindTarget(this);
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref)
|
||||
{
|
||||
if (!ref)
|
||||
{
|
||||
ref = this;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
if (gGLManager.mHasDrawBuffers)
|
||||
{ //setup multiple render targets
|
||||
GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0,
|
||||
GL_COLOR_ATTACHMENT1,
|
||||
GL_COLOR_ATTACHMENT2,
|
||||
GL_COLOR_ATTACHMENT3};
|
||||
glDrawBuffersARB(ref->mTex.size(), drawbuffers);
|
||||
}
|
||||
|
||||
check_framebuffer_status();
|
||||
|
||||
glViewport(0, 0, mResX, mResY);
|
||||
|
||||
sBoundTarget = this;
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo )
|
||||
{
|
||||
allocate(resx,resy,color_fmt,depth,stencil,usage,use_fbo,2);
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, U32 samples )
|
||||
{
|
||||
stop_glerror();
|
||||
mResX = resx;
|
||||
mResY = resy;
|
||||
|
||||
mUsage = usage;
|
||||
mUseDepth = depth;
|
||||
mStencil = stencil;
|
||||
|
||||
release();
|
||||
|
||||
mSamples = samples;
|
||||
|
||||
if (mSamples <= 1)
|
||||
{
|
||||
llerrs << "Cannot create a multisample buffer with less than 2 samples." << llendl;
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
|
||||
if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
|
||||
{
|
||||
|
||||
if (depth)
|
||||
{
|
||||
stop_glerror();
|
||||
allocateDepth();
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
glGenFramebuffers(1, (GLuint *) &mFBO);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
|
||||
if (mDepth)
|
||||
{
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth);
|
||||
if (mStencil)
|
||||
{
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth);
|
||||
}
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
addColorAttachment(color_fmt);
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::addColorAttachment(U32 color_fmt)
|
||||
{
|
||||
if (color_fmt == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
U32 offset = mTex.size();
|
||||
if (offset >= 4 ||
|
||||
(offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers)))
|
||||
{
|
||||
llerrs << "Too many color attachments!" << llendl;
|
||||
}
|
||||
|
||||
U32 tex;
|
||||
glGenRenderbuffers(1, &tex);
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, tex);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, color_fmt, mResX, mResY);
|
||||
stop_glerror();
|
||||
|
||||
if (mFBO)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset, GL_RENDERBUFFER, tex);
|
||||
stop_glerror();
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
switch (status)
|
||||
{
|
||||
case GL_FRAMEBUFFER_COMPLETE:
|
||||
break;
|
||||
default:
|
||||
llerrs << "WTF? " << std::hex << status << llendl;
|
||||
break;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
mTex.push_back(tex);
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::allocateDepth()
|
||||
{
|
||||
glGenRenderbuffers(1, (GLuint* ) &mDepth);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, mDepth);
|
||||
if (mStencil)
|
||||
{
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, GL_DEPTH24_STENCIL8, mResX, mResY);
|
||||
}
|
||||
else
|
||||
{
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, GL_DEPTH_COMPONENT16, mResX, mResY);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,10 +71,7 @@ public:
|
|||
//allocate resources for rendering
|
||||
//must be called before use
|
||||
//multiple calls will release previously allocated resources
|
||||
void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = FALSE);
|
||||
|
||||
//provide this render target with a multisample resource.
|
||||
void setSampleBuffer(LLMultisampleBuffer* buffer);
|
||||
void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = false, S32 samples = 0);
|
||||
|
||||
//add color buffer attachment
|
||||
//limit of 4 color attachments per render target
|
||||
|
|
@ -141,7 +138,6 @@ public:
|
|||
static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; }
|
||||
|
||||
protected:
|
||||
friend class LLMultisampleBuffer;
|
||||
U32 mResX;
|
||||
U32 mResY;
|
||||
std::vector<U32> mTex;
|
||||
|
|
@ -152,26 +148,8 @@ protected:
|
|||
bool mRenderDepth;
|
||||
LLTexUnit::eTextureType mUsage;
|
||||
U32 mSamples;
|
||||
LLMultisampleBuffer* mSampleBuffer;
|
||||
|
||||
static LLRenderTarget* sBoundTarget;
|
||||
|
||||
};
|
||||
|
||||
class LLMultisampleBuffer : public LLRenderTarget
|
||||
{
|
||||
public:
|
||||
LLMultisampleBuffer();
|
||||
virtual ~LLMultisampleBuffer();
|
||||
|
||||
virtual void release();
|
||||
|
||||
virtual void bindTarget();
|
||||
void bindTarget(LLRenderTarget* ref);
|
||||
virtual void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo);
|
||||
void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, U32 samples);
|
||||
virtual void addColorAttachment(U32 color_fmt);
|
||||
virtual void allocateDepth();
|
||||
static LLRenderTarget* sBoundTarget;
|
||||
};
|
||||
|
||||
#endif //!LL_MESA_HEADLESS
|
||||
|
|
|
|||
|
|
@ -209,17 +209,39 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
|||
|
||||
if (features->hasWaterFog)
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightWaterF.glsl"))
|
||||
if (features->disableTextureIndex)
|
||||
{
|
||||
return FALSE;
|
||||
if (!shader->attachObject("lighting/lightWaterNonIndexedF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightWaterF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightF.glsl"))
|
||||
if (features->disableTextureIndex)
|
||||
{
|
||||
return FALSE;
|
||||
if (!shader->attachObject("lighting/lightNonIndexedF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -230,32 +252,76 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
|||
|
||||
if (features->isShiny && features->hasWaterFog)
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightFullbrightShinyWaterF.glsl"))
|
||||
if (features->disableTextureIndex)
|
||||
{
|
||||
return FALSE;
|
||||
if (!shader->attachObject("lighting/lightFullbrightShinyWaterNonIndexedF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightFullbrightShinyWaterF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
}
|
||||
}
|
||||
else if (features->hasWaterFog)
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl"))
|
||||
if (features->disableTextureIndex)
|
||||
{
|
||||
return FALSE;
|
||||
if (!shader->attachObject("lighting/lightFullbrightWaterNonIndexedF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
}
|
||||
}
|
||||
|
||||
else if (features->isShiny)
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightFullbrightShinyF.glsl"))
|
||||
if (features->disableTextureIndex)
|
||||
{
|
||||
return FALSE;
|
||||
if (!shader->attachObject("lighting/lightFullbrightShinyNonIndexedF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightFullbrightShinyF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightFullbrightF.glsl"))
|
||||
if (features->disableTextureIndex)
|
||||
{
|
||||
return FALSE;
|
||||
if (!shader->attachObject("lighting/lightFullbrightNonIndexedF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightFullbrightF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -266,17 +332,39 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
|||
|
||||
if (features->hasWaterFog)
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightShinyWaterF.glsl"))
|
||||
if (features->disableTextureIndex)
|
||||
{
|
||||
return FALSE;
|
||||
if (!shader->attachObject("lighting/lightShinyWaterNonIndexedF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightShinyWaterF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightShinyF.glsl"))
|
||||
if (features->disableTextureIndex)
|
||||
{
|
||||
return FALSE;
|
||||
if (!shader->attachObject("lighting/lightShinyNonIndexedF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightShinyF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -315,12 +403,12 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
|
|||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS("ShaderLoading") << log << LL_ENDL;
|
||||
LL_DEBUGS("ShaderLoading") << log << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type)
|
||||
GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels)
|
||||
{
|
||||
GLenum error = GL_NO_ERROR;
|
||||
if (gDebugGL)
|
||||
|
|
@ -374,6 +462,106 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
|
|||
GLcharARB* text[1024];
|
||||
GLuint count = 0;
|
||||
|
||||
if (gGLManager.mGLVersion < 3.f)
|
||||
{
|
||||
//set version to 1.20
|
||||
text[count++] = strdup("#version 120\n");
|
||||
}
|
||||
else
|
||||
{ //set version to 1.30
|
||||
text[count++] = strdup("#version 130\n");
|
||||
}
|
||||
|
||||
//copy preprocessor definitions into buffer
|
||||
for (std::map<std::string,std::string>::iterator iter = mDefinitions.begin(); iter != mDefinitions.end(); ++iter)
|
||||
{
|
||||
std::string define = "#define " + iter->first + " " + iter->second + "\n";
|
||||
text[count++] = (GLcharARB *) strdup(define.c_str());
|
||||
}
|
||||
|
||||
if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER_ARB)
|
||||
{
|
||||
//use specified number of texture channels for indexed texture rendering
|
||||
|
||||
/* prepend shader code that looks like this:
|
||||
|
||||
uniform sampler2D tex0;
|
||||
uniform sampler2D tex1;
|
||||
uniform sampler2D tex2;
|
||||
.
|
||||
.
|
||||
.
|
||||
uniform sampler2D texN;
|
||||
|
||||
varying float vary_texture_index;
|
||||
|
||||
vec4 diffuseLookup(vec2 texcoord)
|
||||
{
|
||||
switch (int(vary_texture_index+0.25))
|
||||
{
|
||||
case 0: return texture2D(tex0, texcoord);
|
||||
case 1: return texture2D(tex1, texcoord);
|
||||
case 2: return texture2D(tex2, texcoord);
|
||||
.
|
||||
.
|
||||
.
|
||||
case N: return texture2D(texN, texcoord);
|
||||
}
|
||||
|
||||
return vec4(0,0,0,0);
|
||||
}
|
||||
*/
|
||||
|
||||
//uniform declartion
|
||||
for (S32 i = 0; i < texture_index_channels; ++i)
|
||||
{
|
||||
std::string decl = llformat("uniform sampler2D tex%d;\n", i);
|
||||
text[count++] = strdup(decl.c_str());
|
||||
}
|
||||
|
||||
text[count++] = strdup("varying float vary_texture_index;\n");
|
||||
text[count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n");
|
||||
text[count++] = strdup("{\n");
|
||||
|
||||
|
||||
if (gGLManager.mGLVersion >= 3.f)
|
||||
{
|
||||
text[count++] = strdup("\tswitch (int(vary_texture_index+0.25))\n");
|
||||
text[count++] = strdup("\t{\n");
|
||||
|
||||
//switch body
|
||||
for (S32 i = 0; i < texture_index_channels; ++i)
|
||||
{
|
||||
std::string case_str = llformat("\t\tcase %d: return texture2D(tex%d, texcoord);\n", i, i);
|
||||
text[count++] = strdup(case_str.c_str());
|
||||
}
|
||||
|
||||
text[count++] = strdup("\t}\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
//switches aren't supported, make block that looks like:
|
||||
/*
|
||||
int ti = int(vary_texture_index+0.25);
|
||||
if (ti == 0) return texture2D(tex0, texcoord);
|
||||
if (ti == 1) return texture2D(tex1, texcoord);
|
||||
.
|
||||
.
|
||||
.
|
||||
if (ti == N) return texture2D(texN, texcoord);
|
||||
*/
|
||||
|
||||
text[count++] = strdup("int ti = int(vary_texture_index+0.25);\n");
|
||||
for (S32 i = 0; i < texture_index_channels; ++i)
|
||||
{
|
||||
std::string if_str = llformat("if (ti == %d) return texture2D(tex%d, texcoord);\n", i, i);
|
||||
text[count++] = strdup(if_str.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
text[count++] = strdup("\treturn vec4(0,0,0,0);\n");
|
||||
text[count++] = strdup("}\n");
|
||||
}
|
||||
|
||||
//copy file into memory
|
||||
while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(buff) )
|
||||
|
|
@ -457,7 +645,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
|
|||
if (shader_level > 1)
|
||||
{
|
||||
shader_level--;
|
||||
return loadShaderFile(filename,shader_level,type);
|
||||
return loadShaderFile(filename,shader_level,type,texture_index_channels);
|
||||
}
|
||||
LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public:
|
|||
void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE);
|
||||
BOOL linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);
|
||||
BOOL validateProgramObject(GLhandleARB obj);
|
||||
GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type);
|
||||
GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels = -1);
|
||||
|
||||
// Implemented in the application to actually point to the shader directory.
|
||||
virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual
|
||||
|
|
@ -60,6 +60,9 @@ public:
|
|||
|
||||
std::vector<std::string> mReservedUniforms;
|
||||
|
||||
//preprocessor definitions (name/value)
|
||||
std::map<std::string, std::string> mDefinitions;
|
||||
|
||||
protected:
|
||||
|
||||
// our parameter manager singleton instance
|
||||
|
|
|
|||
|
|
@ -934,8 +934,26 @@ void LLVertexBuffer::allocateClientIndexBuffer()
|
|||
}
|
||||
}
|
||||
|
||||
bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
|
||||
{
|
||||
S32 end = index+count;
|
||||
S32 region_end = region.mIndex+region.mCount;
|
||||
|
||||
if (end < region.mIndex ||
|
||||
index > region_end)
|
||||
{ //gap exists, do not merge
|
||||
return false;
|
||||
}
|
||||
|
||||
S32 new_end = llmax(end, region_end);
|
||||
S32 new_index = llmin(index, region.mIndex);
|
||||
region.mIndex = new_index;
|
||||
region.mCount = new_end-new_index;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Map for data access
|
||||
U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access)
|
||||
U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)
|
||||
{
|
||||
LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
|
||||
if (mFinal)
|
||||
|
|
@ -947,8 +965,45 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access)
|
|||
llerrs << "LLVertexBuffer::mapVertexBuffer() called on unallocated buffer." << llendl;
|
||||
}
|
||||
|
||||
if (!mVertexLocked && useVBOs())
|
||||
if (useVBOs())
|
||||
{
|
||||
|
||||
if (sDisableVBOMapping || gGLManager.mHasMapBufferRange)
|
||||
{
|
||||
if (count == -1)
|
||||
{
|
||||
count = mNumVerts-index;
|
||||
}
|
||||
|
||||
bool mapped = false;
|
||||
//see if range is already mapped
|
||||
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
|
||||
{
|
||||
MappedRegion& region = mMappedVertexRegions[i];
|
||||
if (region.mType == type)
|
||||
{
|
||||
if (expand_region(region, index, count))
|
||||
{
|
||||
mapped = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mapped)
|
||||
{
|
||||
//not already mapped, map new region
|
||||
MappedRegion region(type, !sDisableVBOMapping && map_range ? -1 : index, count);
|
||||
mMappedVertexRegions.push_back(region);
|
||||
}
|
||||
}
|
||||
|
||||
if (mVertexLocked && map_range)
|
||||
{
|
||||
llerrs << "Attempted to map a specific range of a buffer that was already mapped." << llendl;
|
||||
}
|
||||
|
||||
if (!mVertexLocked)
|
||||
{
|
||||
LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES);
|
||||
setBuffer(0, type);
|
||||
|
|
@ -957,61 +1012,95 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access)
|
|||
|
||||
if(sDisableVBOMapping)
|
||||
{
|
||||
map_range = false;
|
||||
allocateClientVertexBuffer() ;
|
||||
}
|
||||
else
|
||||
{
|
||||
U8* src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
|
||||
U8* src = NULL;
|
||||
#ifdef GL_ARB_map_buffer_range
|
||||
if (gGLManager.mHasMapBufferRange)
|
||||
{
|
||||
if (map_range)
|
||||
{
|
||||
S32 offset = mOffsets[type] + sTypeSize[type]*index;
|
||||
S32 length = (sTypeSize[type]*count+0xF) & ~0xF;
|
||||
src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, offset, length, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
|
||||
}
|
||||
}
|
||||
else
|
||||
#else
|
||||
llassert_always(!gGLManager.mHasMapBufferRange);
|
||||
#endif
|
||||
{
|
||||
map_range = false;
|
||||
src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
|
||||
}
|
||||
|
||||
mMappedData = LL_NEXT_ALIGNED_ADDRESS<U8>(src);
|
||||
mAlignedOffset = mMappedData - src;
|
||||
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!mMappedData)
|
||||
{
|
||||
log_glerror();
|
||||
|
||||
if (!mMappedData)
|
||||
{
|
||||
log_glerror();
|
||||
|
||||
//check the availability of memory
|
||||
U32 avail_phy_mem, avail_vir_mem;
|
||||
LLMemoryInfo::getAvailableMemoryKB(avail_phy_mem, avail_vir_mem) ;
|
||||
llinfos << "Available physical mwmory(KB): " << avail_phy_mem << llendl ;
|
||||
llinfos << "Available virtual memory(KB): " << avail_vir_mem << llendl;
|
||||
//check the availability of memory
|
||||
U32 avail_phy_mem, avail_vir_mem;
|
||||
LLMemoryInfo::getAvailableMemoryKB(avail_phy_mem, avail_vir_mem) ;
|
||||
llinfos << "Available physical mwmory(KB): " << avail_phy_mem << llendl ;
|
||||
llinfos << "Available virtual memory(KB): " << avail_vir_mem << llendl;
|
||||
|
||||
if(!sDisableVBOMapping)
|
||||
{
|
||||
//--------------------
|
||||
//print out more debug info before crash
|
||||
llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
|
||||
GLint size ;
|
||||
glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ;
|
||||
llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ;
|
||||
//--------------------
|
||||
if(!sDisableVBOMapping)
|
||||
{
|
||||
//--------------------
|
||||
//print out more debug info before crash
|
||||
llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
|
||||
GLint size ;
|
||||
glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ;
|
||||
llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ;
|
||||
//--------------------
|
||||
|
||||
GLint buff;
|
||||
glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
|
||||
if ((GLuint)buff != mGLBuffer)
|
||||
{
|
||||
llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
|
||||
}
|
||||
GLint buff;
|
||||
glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
|
||||
if ((GLuint)buff != mGLBuffer)
|
||||
{
|
||||
llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
|
||||
}
|
||||
|
||||
|
||||
llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "memory allocation for vertex data failed." << llendl ;
|
||||
llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "memory allocation for vertex data failed." << llendl ;
|
||||
}
|
||||
}
|
||||
sMappedCount++;
|
||||
}
|
||||
sMappedCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
map_range = false;
|
||||
}
|
||||
|
||||
return mMappedData;
|
||||
if (map_range && !sDisableVBOMapping)
|
||||
{
|
||||
return mMappedData;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mMappedData+mOffsets[type]+sTypeSize[type]*index;
|
||||
}
|
||||
}
|
||||
|
||||
U8* LLVertexBuffer::mapIndexBuffer(S32 access)
|
||||
U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
|
||||
{
|
||||
LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
|
||||
if (mFinal)
|
||||
|
|
@ -1023,8 +1112,41 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 access)
|
|||
llerrs << "LLVertexBuffer::mapIndexBuffer() called on unallocated buffer." << llendl;
|
||||
}
|
||||
|
||||
if (!mIndexLocked && useVBOs())
|
||||
if (useVBOs())
|
||||
{
|
||||
if (sDisableVBOMapping || gGLManager.mHasMapBufferRange)
|
||||
{
|
||||
if (count == -1)
|
||||
{
|
||||
count = mNumIndices-index;
|
||||
}
|
||||
|
||||
bool mapped = false;
|
||||
//see if range is already mapped
|
||||
for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
|
||||
{
|
||||
MappedRegion& region = mMappedIndexRegions[i];
|
||||
if (expand_region(region, index, count))
|
||||
{
|
||||
mapped = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mapped)
|
||||
{
|
||||
//not already mapped, map new region
|
||||
MappedRegion region(TYPE_INDEX, !sDisableVBOMapping && map_range ? -1 : index, count);
|
||||
mMappedIndexRegions.push_back(region);
|
||||
}
|
||||
}
|
||||
|
||||
if (mIndexLocked && map_range)
|
||||
{
|
||||
llerrs << "Attempted to map a specific range of a buffer that was already mapped." << llendl;
|
||||
}
|
||||
|
||||
if (!mIndexLocked)
|
||||
{
|
||||
LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);
|
||||
|
||||
|
|
@ -1034,12 +1156,36 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 access)
|
|||
|
||||
if(sDisableVBOMapping)
|
||||
{
|
||||
map_range = false;
|
||||
allocateClientIndexBuffer() ;
|
||||
}
|
||||
else
|
||||
{
|
||||
U8* src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
|
||||
mMappedIndexData = LL_NEXT_ALIGNED_ADDRESS<U8>(src);
|
||||
U8* src = NULL;
|
||||
#ifdef GL_ARB_map_buffer_range
|
||||
if (gGLManager.mHasMapBufferRange)
|
||||
{
|
||||
if (map_range)
|
||||
{
|
||||
S32 offset = sizeof(U16)*index;
|
||||
S32 length = sizeof(U16)*count;
|
||||
src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, sizeof(U16)*mNumIndices, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
|
||||
}
|
||||
}
|
||||
else
|
||||
#else
|
||||
llassert_always(!gGLManager.mHasMapBufferRange);
|
||||
#endif
|
||||
{
|
||||
map_range = false;
|
||||
src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
|
||||
}
|
||||
|
||||
mMappedIndexData = src; //LL_NEXT_ALIGNED_ADDRESS<U8>(src);
|
||||
mAlignedIndexOffset = mMappedIndexData - src;
|
||||
stop_glerror();
|
||||
}
|
||||
|
|
@ -1068,31 +1214,81 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 access)
|
|||
|
||||
sMappedCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
map_range = false;
|
||||
}
|
||||
|
||||
return mMappedIndexData ;
|
||||
if (map_range && !sDisableVBOMapping)
|
||||
{
|
||||
return mMappedIndexData;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mMappedIndexData + sizeof(U16)*index;
|
||||
}
|
||||
}
|
||||
|
||||
void LLVertexBuffer::unmapBuffer(S32 type)
|
||||
{
|
||||
LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER);
|
||||
if (!useVBOs())
|
||||
if (!useVBOs() || type == -2)
|
||||
{
|
||||
return ; //nothing to unmap
|
||||
}
|
||||
|
||||
bool updated_all = false ;
|
||||
|
||||
if (mMappedData && mVertexLocked && type != TYPE_INDEX)
|
||||
{
|
||||
updated_all = (mIndexLocked && type < 0) ; //both vertex and index buffers done updating
|
||||
|
||||
if(sDisableVBOMapping)
|
||||
{
|
||||
stop_glerror();
|
||||
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData);
|
||||
stop_glerror();
|
||||
if (!mMappedVertexRegions.empty())
|
||||
{
|
||||
stop_glerror();
|
||||
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
|
||||
{
|
||||
const MappedRegion& region = mMappedVertexRegions[i];
|
||||
S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0;
|
||||
S32 length = sTypeSize[region.mType]*region.mCount;
|
||||
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, mMappedData+offset);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
mMappedVertexRegions.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
stop_glerror();
|
||||
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef GL_ARB_map_buffer_range
|
||||
if (gGLManager.mHasMapBufferRange)
|
||||
{
|
||||
if (!mMappedVertexRegions.empty())
|
||||
{
|
||||
stop_glerror();
|
||||
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
|
||||
{
|
||||
const MappedRegion& region = mMappedVertexRegions[i];
|
||||
S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0;
|
||||
S32 length = sTypeSize[region.mType]*region.mCount;
|
||||
glFlushMappedBufferRange(GL_ARRAY_BUFFER_ARB, offset, length);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
mMappedVertexRegions.clear();
|
||||
}
|
||||
}
|
||||
#else
|
||||
llassert_always(!gGLManager.mHasMapBufferRange);
|
||||
#endif
|
||||
stop_glerror();
|
||||
glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
|
||||
stop_glerror();
|
||||
|
|
@ -1103,17 +1299,53 @@ void LLVertexBuffer::unmapBuffer(S32 type)
|
|||
mVertexLocked = FALSE ;
|
||||
sMappedCount--;
|
||||
}
|
||||
|
||||
if(mMappedIndexData && mIndexLocked && (type < 0 || type == TYPE_INDEX))
|
||||
|
||||
if (mMappedIndexData && mIndexLocked && (type < 0 || type == TYPE_INDEX))
|
||||
{
|
||||
if(sDisableVBOMapping)
|
||||
{
|
||||
stop_glerror();
|
||||
glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData);
|
||||
stop_glerror();
|
||||
if (!mMappedIndexRegions.empty())
|
||||
{
|
||||
for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
|
||||
{
|
||||
const MappedRegion& region = mMappedIndexRegions[i];
|
||||
S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
|
||||
S32 length = sizeof(U16)*region.mCount;
|
||||
glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, mMappedIndexData+offset);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
mMappedIndexRegions.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
stop_glerror();
|
||||
glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef GL_ARB_map_buffer_range
|
||||
if (gGLManager.mHasMapBufferRange)
|
||||
{
|
||||
if (!mMappedIndexRegions.empty())
|
||||
{
|
||||
for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
|
||||
{
|
||||
const MappedRegion& region = mMappedIndexRegions[i];
|
||||
S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
|
||||
S32 length = sizeof(U16)*region.mCount;
|
||||
glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
mMappedIndexRegions.clear();
|
||||
}
|
||||
}
|
||||
#else
|
||||
llassert_always(!gGLManager.mHasMapBufferRange);
|
||||
#endif
|
||||
stop_glerror();
|
||||
glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
|
||||
stop_glerror();
|
||||
|
|
@ -1152,19 +1384,19 @@ template <class T,S32 type> struct VertexBufferStrider
|
|||
typedef LLStrider<T> strider_t;
|
||||
static bool get(LLVertexBuffer& vbo,
|
||||
strider_t& strider,
|
||||
S32 index)
|
||||
S32 index, S32 count, bool map_range)
|
||||
{
|
||||
if (type == LLVertexBuffer::TYPE_INDEX)
|
||||
{
|
||||
S32 stride = sizeof(T);
|
||||
U8* ptr = vbo.mapIndexBuffer(index, count, map_range);
|
||||
|
||||
if (vbo.mapIndexBuffer() == NULL)
|
||||
if (ptr == NULL)
|
||||
{
|
||||
llwarns << "mapIndexBuffer failed!" << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
strider = (T*)(vbo.getMappedIndices() + index*stride);
|
||||
strider = (T*)ptr;
|
||||
strider.setStride(0);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -1172,13 +1404,15 @@ template <class T,S32 type> struct VertexBufferStrider
|
|||
{
|
||||
S32 stride = LLVertexBuffer::sTypeSize[type];
|
||||
|
||||
if (vbo.mapVertexBuffer(type) == NULL)
|
||||
U8* ptr = vbo.mapVertexBuffer(type, index, count, map_range);
|
||||
|
||||
if (ptr == NULL)
|
||||
{
|
||||
llwarns << "mapVertexBuffer failed!" << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
strider = (T*)(vbo.getMappedData() + vbo.getOffset(type)+index*stride);
|
||||
strider = (T*)ptr;
|
||||
strider.setStride(stride);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -1190,55 +1424,48 @@ template <class T,S32 type> struct VertexBufferStrider
|
|||
}
|
||||
};
|
||||
|
||||
bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector3>& strider, S32 index)
|
||||
bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
|
||||
{
|
||||
return VertexBufferStrider<LLVector3,TYPE_VERTEX>::get(*this, strider, index);
|
||||
return VertexBufferStrider<LLVector3,TYPE_VERTEX>::get(*this, strider, index, count, map_range);
|
||||
}
|
||||
bool LLVertexBuffer::getIndexStrider(LLStrider<U16>& strider, S32 index)
|
||||
bool LLVertexBuffer::getIndexStrider(LLStrider<U16>& strider, S32 index, S32 count, bool map_range)
|
||||
{
|
||||
return VertexBufferStrider<U16,TYPE_INDEX>::get(*this, strider, index);
|
||||
return VertexBufferStrider<U16,TYPE_INDEX>::get(*this, strider, index, count, map_range);
|
||||
}
|
||||
bool LLVertexBuffer::getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index)
|
||||
bool LLVertexBuffer::getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index, S32 count, bool map_range)
|
||||
{
|
||||
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD0>::get(*this, strider, index);
|
||||
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD0>::get(*this, strider, index, count, map_range);
|
||||
}
|
||||
bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index)
|
||||
bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index, S32 count, bool map_range)
|
||||
{
|
||||
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index);
|
||||
}
|
||||
/*bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index)
|
||||
{
|
||||
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index);
|
||||
}
|
||||
bool LLVertexBuffer::getTexCoord3Strider(LLStrider<LLVector2>& strider, S32 index)
|
||||
{
|
||||
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD3>::get(*this, strider, index);
|
||||
}*/
|
||||
bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index)
|
||||
{
|
||||
return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index);
|
||||
}
|
||||
bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index)
|
||||
{
|
||||
return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index);
|
||||
}
|
||||
bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index)
|
||||
{
|
||||
return VertexBufferStrider<LLColor4U,TYPE_COLOR>::get(*this, strider, index);
|
||||
}
|
||||
bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, S32 index)
|
||||
{
|
||||
return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index);
|
||||
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index, count, map_range);
|
||||
}
|
||||
|
||||
bool LLVertexBuffer::getWeight4Strider(LLStrider<LLVector4>& strider, S32 index)
|
||||
bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
|
||||
{
|
||||
return VertexBufferStrider<LLVector4,TYPE_WEIGHT4>::get(*this, strider, index);
|
||||
return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count, map_range);
|
||||
}
|
||||
bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
|
||||
{
|
||||
return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index, count, map_range);
|
||||
}
|
||||
bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index, S32 count, bool map_range)
|
||||
{
|
||||
return VertexBufferStrider<LLColor4U,TYPE_COLOR>::get(*this, strider, index, count, map_range);
|
||||
}
|
||||
bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, S32 index, S32 count, bool map_range)
|
||||
{
|
||||
return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index, count, map_range);
|
||||
}
|
||||
|
||||
bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index)
|
||||
bool LLVertexBuffer::getWeight4Strider(LLStrider<LLVector4>& strider, S32 index, S32 count, bool map_range)
|
||||
{
|
||||
return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index);
|
||||
return VertexBufferStrider<LLVector4,TYPE_WEIGHT4>::get(*this, strider, index, count, map_range);
|
||||
}
|
||||
|
||||
bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index, S32 count, bool map_range)
|
||||
{
|
||||
return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index, count, map_range);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
@ -1497,17 +1724,16 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
|
|||
}
|
||||
if (data_mask & MAP_VERTEX)
|
||||
{
|
||||
glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
|
||||
if (data_mask & MAP_TEXTURE_INDEX)
|
||||
{
|
||||
glVertexPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
|
||||
}
|
||||
}
|
||||
|
||||
llglassertok();
|
||||
}
|
||||
|
||||
void LLVertexBuffer::markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count)
|
||||
{
|
||||
// TODO: use GL_APPLE_flush_buffer_range here
|
||||
/*if (useVBOs() && !mFilthy)
|
||||
{
|
||||
|
||||
}*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,18 @@ protected:
|
|||
class LLVertexBuffer : public LLRefCount
|
||||
{
|
||||
public:
|
||||
class MappedRegion
|
||||
{
|
||||
public:
|
||||
S32 mType;
|
||||
S32 mIndex;
|
||||
S32 mCount;
|
||||
|
||||
MappedRegion(S32 type, S32 index, S32 count)
|
||||
: mType(type), mIndex(index), mCount(count)
|
||||
{ }
|
||||
};
|
||||
|
||||
LLVertexBuffer(const LLVertexBuffer& rhs)
|
||||
{
|
||||
*this = rhs;
|
||||
|
|
@ -130,6 +142,9 @@ public:
|
|||
TYPE_CLOTHWEIGHT,
|
||||
TYPE_MAX,
|
||||
TYPE_INDEX,
|
||||
|
||||
//no actual additional data, but indicates position.w is texture index
|
||||
TYPE_TEXTURE_INDEX,
|
||||
};
|
||||
enum {
|
||||
MAP_VERTEX = (1<<TYPE_VERTEX),
|
||||
|
|
@ -144,6 +159,7 @@ public:
|
|||
MAP_WEIGHT = (1<<TYPE_WEIGHT),
|
||||
MAP_WEIGHT4 = (1<<TYPE_WEIGHT4),
|
||||
MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT),
|
||||
MAP_TEXTURE_INDEX = (1<<TYPE_TEXTURE_INDEX),
|
||||
};
|
||||
|
||||
protected:
|
||||
|
|
@ -173,8 +189,8 @@ public:
|
|||
LLVertexBuffer(U32 typemask, S32 usage);
|
||||
|
||||
// map for data access
|
||||
U8* mapVertexBuffer(S32 type = -1, S32 access = -1);
|
||||
U8* mapIndexBuffer(S32 access = -1);
|
||||
U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range);
|
||||
U8* mapIndexBuffer(S32 index, S32 count, bool map_range);
|
||||
|
||||
// set for rendering
|
||||
virtual void setBuffer(U32 data_mask, S32 type = -1); // calls setupVertexBuffer() if data_mask is not 0
|
||||
|
|
@ -189,16 +205,16 @@ public:
|
|||
// vb->getNormalStrider(norms);
|
||||
// setVertsNorms(verts, norms);
|
||||
// vb->unmapBuffer();
|
||||
bool getVertexStrider(LLStrider<LLVector3>& strider, S32 index=0);
|
||||
bool getIndexStrider(LLStrider<U16>& strider, S32 index=0);
|
||||
bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0);
|
||||
bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0);
|
||||
bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0);
|
||||
bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0);
|
||||
bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0);
|
||||
bool getWeightStrider(LLStrider<F32>& strider, S32 index=0);
|
||||
bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0);
|
||||
bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0);
|
||||
bool getVertexStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getIndexStrider(LLStrider<U16>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getWeightStrider(LLStrider<F32>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
|
||||
BOOL isEmpty() const { return mEmpty; }
|
||||
BOOL isLocked() const { return mVertexLocked || mIndexLocked; }
|
||||
|
|
@ -218,8 +234,6 @@ public:
|
|||
S32 getOffset(S32 type) const { return mOffsets[type]; }
|
||||
S32 getUsage() const { return mUsage; }
|
||||
|
||||
void markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count);
|
||||
|
||||
void draw(U32 mode, U32 count, U32 indices_offset) const;
|
||||
void drawArrays(U32 mode, U32 offset, U32 count) const;
|
||||
void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const;
|
||||
|
|
@ -253,20 +267,8 @@ protected:
|
|||
BOOL mDynamicSize; // if TRUE, buffer has been resized at least once (and should be padded)
|
||||
S32 mOffsets[TYPE_MAX];
|
||||
|
||||
class DirtyRegion
|
||||
{
|
||||
public:
|
||||
U32 mIndex;
|
||||
U32 mCount;
|
||||
U32 mIndicesIndex;
|
||||
U32 mIndicesCount;
|
||||
|
||||
DirtyRegion(U32 vi, U32 vc, U32 ii, U32 ic)
|
||||
: mIndex(vi), mCount(vc), mIndicesIndex(ii), mIndicesCount(ic)
|
||||
{ }
|
||||
};
|
||||
|
||||
std::vector<DirtyRegion> mDirtyRegions; //vector of dirty regions to rebuild
|
||||
std::vector<MappedRegion> mMappedVertexRegions;
|
||||
std::vector<MappedRegion> mMappedIndexRegions;
|
||||
|
||||
public:
|
||||
static S32 sCount;
|
||||
|
|
|
|||
|
|
@ -337,7 +337,7 @@ LLLocale::LLLocale(const std::string& locale_string)
|
|||
char* new_locale_string = setlocale( LC_ALL, locale_string.c_str());
|
||||
if ( new_locale_string == NULL)
|
||||
{
|
||||
llwarns << "Failed to set locale " << locale_string << llendl;
|
||||
LL_WARNS_ONCE("LLLocale") << "Failed to set locale " << locale_string << LL_ENDL;
|
||||
setlocale(LC_ALL, SYSTEM_LOCALE.c_str());
|
||||
}
|
||||
//else
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ LLSpinCtrl::Params::Params()
|
|||
: label_width("label_width"),
|
||||
decimal_digits("decimal_digits"),
|
||||
allow_text_entry("allow_text_entry", true),
|
||||
label_wrap("label_wrap", false),
|
||||
text_enabled_color("text_enabled_color"),
|
||||
text_disabled_color("text_disabled_color"),
|
||||
up_button("up_button"),
|
||||
|
|
@ -80,6 +81,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
|
|||
{
|
||||
LLRect label_rect( 0, centered_top, label_width, centered_bottom );
|
||||
LLTextBox::Params params;
|
||||
params.wrap(p.label_wrap);
|
||||
params.name("SpinCtrl Label");
|
||||
params.rect(label_rect);
|
||||
params.initial_value(p.label());
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ public:
|
|||
Optional<S32> label_width;
|
||||
Optional<U32> decimal_digits;
|
||||
Optional<bool> allow_text_entry;
|
||||
Optional<bool> label_wrap;
|
||||
|
||||
Optional<LLUIColor> text_enabled_color;
|
||||
Optional<LLUIColor> text_disabled_color;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
<key>tags</key>
|
||||
<array>
|
||||
<string>AppInit</string>
|
||||
<string>Capabilities</string>
|
||||
<string>SystemInfo</string>
|
||||
<string>TextureCache</string>
|
||||
<string>AppCache</string>
|
||||
|
|
@ -43,6 +44,7 @@
|
|||
<array>
|
||||
<!-- sample entry for debugging a specific item -->
|
||||
<!-- <string>Voice</string> -->
|
||||
<string>Capabilities</string>
|
||||
</array>
|
||||
</map>
|
||||
</array>
|
||||
|
|
|
|||
|
|
@ -3058,6 +3058,17 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>EnableGestureSounds</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Play sounds from gestures</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>EnableMouselook</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -3256,17 +3267,6 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FirstLoginThisInstall</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Specifies that you have not successfully logged in since you installed the latest update</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FirstName</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -5589,10 +5589,10 @@
|
|||
<key>Value</key>
|
||||
<real>0</real>
|
||||
</map>
|
||||
<key>MeshUseWholeModelUpload</key>
|
||||
<key>MeshUploadLogXML</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Upload model in its entirety instead of mesh-by-mesh (new caps)</string>
|
||||
<string>Verbose XML logging on mesh upload</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -5600,6 +5600,17 @@
|
|||
<key>Value</key>
|
||||
<real>0</real>
|
||||
</map>
|
||||
<key>MeshUploadFakeErrors</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Force upload errors (for testing)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<real>0</real>
|
||||
</map>
|
||||
<key>MigrateCacheDirectory</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -7102,7 +7113,76 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>RenderAnisotropic</key>
|
||||
|
||||
<key>OctreeMaxNodeCapacity</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Maximum number of elements to store in a single octree node</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>128</integer>
|
||||
</map>
|
||||
|
||||
<key>OctreeStaticObjectSizeFactor</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Multiplier on static object size for determining octree node size </string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>4</integer>
|
||||
</map>
|
||||
|
||||
<key>OctreeAlphaDistanceFactor</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Multiplier on alpha object distance for determining octree node size </string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Vector3</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>0.1</real>
|
||||
<real>0.0</real>
|
||||
<real>0.0</real>
|
||||
</array>
|
||||
</map>
|
||||
|
||||
<key>OctreeAttachmentSizeFactor</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Multiplier on attachment size for determining octree node size </string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>4</integer>
|
||||
</map>
|
||||
|
||||
<key>OctreeDistanceFactor</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Multiplier on distance for determining octree node size </string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Vector3</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>0.01</real>
|
||||
<real>0.0</real>
|
||||
<real>0.0</real>
|
||||
</array>
|
||||
</map>
|
||||
|
||||
<key>RenderAnisotropic</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Render textures using anisotropic filtering</string>
|
||||
|
|
@ -7199,7 +7279,7 @@
|
|||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<integer>1.0</integer>
|
||||
<real>1.0</real>
|
||||
</map>
|
||||
<key>RenderAvatarVP</key>
|
||||
<map>
|
||||
|
|
@ -7455,6 +7535,17 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderMaxTextureIndex</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Maximum texture index to use for indexed texture rendering.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>6</integer>
|
||||
</map>
|
||||
<key>RenderDebugTextureBind</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -8600,7 +8691,7 @@
|
|||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>8192</integer>
|
||||
<integer>65536</integer>
|
||||
</map>
|
||||
<key>RenderMaxVBOSize</key>
|
||||
<map>
|
||||
|
|
@ -8868,17 +8959,6 @@
|
|||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderUseTriStrips</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Use triangle strips for rendering prims.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderUseTriStrips</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Use triangle strips for rendering prims.</string>
|
||||
|
|
@ -8953,7 +9033,7 @@
|
|||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderUseStreamVBO</key>
|
||||
<map>
|
||||
|
|
@ -9063,7 +9143,7 @@
|
|||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>3.0</real>
|
||||
<real>2.0</real>
|
||||
</map>
|
||||
<key>MeshThreadCount</key>
|
||||
<map>
|
||||
|
|
@ -9659,6 +9739,17 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>NearbyListShowMap</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Show/hide map above nearby people list</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>NearbyListShowIcons</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -12406,7 +12497,7 @@
|
|||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
<integer>20</integer>
|
||||
</map>
|
||||
<key>WaterEditPresets</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
void default_lighting();
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
attribute vec4 weight; //1
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
|
||||
mat4 getSkinnedTransform();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
void default_lighting();
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol);
|
||||
void calcAtmospherics(vec3 inPositionEye);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $License$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
attribute vec4 object_weight;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
mat4 getSkinnedTransform();
|
||||
|
||||
|
|
|
|||
|
|
@ -5,13 +5,14 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
uniform sampler2DRect depthMap;
|
||||
|
||||
vec4 diffuseLookup(vec2 texcoord);
|
||||
|
||||
uniform mat4 shadow_matrix[6];
|
||||
uniform vec4 shadow_clip;
|
||||
uniform vec2 screen_res;
|
||||
|
|
@ -47,7 +48,7 @@ void main()
|
|||
|
||||
vec4 pos = vec4(vary_position, 1.0);
|
||||
|
||||
vec4 diff= texture2D(diffuseMap, gl_TexCoord[0].xy);
|
||||
vec4 diff= diffuseLookup(gl_TexCoord[0].xy);
|
||||
|
||||
vec4 col = vec4(vary_ambient + vary_directional.rgb, gl_Color.a);
|
||||
vec4 color = diff * col;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* @file alphaF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
uniform sampler2DRect depthMap;
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
|
||||
uniform mat4 shadow_matrix[6];
|
||||
uniform vec4 shadow_clip;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
vec3 atmosLighting(vec3 light);
|
||||
vec3 scaleSoftClip(vec3 light);
|
||||
|
||||
varying vec3 vary_ambient;
|
||||
varying vec3 vary_directional;
|
||||
varying vec3 vary_fragcoord;
|
||||
varying vec3 vary_position;
|
||||
varying vec3 vary_pointlight_col;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
float depth = texture2DRect(depthMap, pos_screen.xy).a;
|
||||
vec2 sc = pos_screen.xy*2.0;
|
||||
sc /= screen_res;
|
||||
sc -= vec2(1.0,1.0);
|
||||
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
|
||||
vec4 pos = inv_proj * ndc;
|
||||
pos /= pos.w;
|
||||
pos.w = 1.0;
|
||||
return pos;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
|
||||
frag *= screen_res;
|
||||
|
||||
vec4 pos = vec4(vary_position, 1.0);
|
||||
|
||||
vec4 diff= texture2D(diffuseMap,gl_TexCoord[0].xy);
|
||||
|
||||
vec4 col = vec4(vary_ambient + vary_directional.rgb, gl_Color.a);
|
||||
vec4 color = diff * col;
|
||||
|
||||
color.rgb = atmosLighting(color.rgb);
|
||||
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
|
||||
color.rgb += diff.rgb * vary_pointlight_col.rgb;
|
||||
|
||||
gl_FragColor = color;
|
||||
//gl_FragColor = vec4(1,0,1,1);
|
||||
//gl_FragColor = vec4(1,0,1,1)*shadow;
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
* $License$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
|
||||
mat4 getObjectSkinnedTransform();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
|
||||
void calcAtmospherics(vec3 inPositionEye);
|
||||
|
|
@ -23,6 +23,7 @@ varying vec3 vary_fragcoord;
|
|||
varying vec3 vary_position;
|
||||
varying vec3 vary_light;
|
||||
varying vec3 vary_pointlight_col;
|
||||
varying float vary_texture_index;
|
||||
|
||||
uniform float near_clip;
|
||||
uniform float shadow_offset;
|
||||
|
|
@ -61,11 +62,13 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
|
|||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = ftransform();
|
||||
vec4 vert = vec4(gl_Vertex.xyz, 1.0);
|
||||
vary_texture_index = gl_Vertex.w;
|
||||
gl_Position = gl_ModelViewProjectionMatrix * vert;
|
||||
|
||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
||||
|
||||
vec4 pos = (gl_ModelViewMatrix * gl_Vertex);
|
||||
vec4 pos = (gl_ModelViewMatrix * vert);
|
||||
vec3 norm = normalize(gl_NormalMatrix * gl_Normal);
|
||||
|
||||
float dp_directional_light = max(0.0, dot(norm, gl_LightSource[0].position.xyz));
|
||||
|
|
@ -102,7 +105,7 @@ void main()
|
|||
|
||||
gl_FogFragCoord = pos.z;
|
||||
|
||||
pos = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
pos = gl_ModelViewProjectionMatrix * vert;
|
||||
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $License$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $License$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
mat4 getObjectSkinnedTransform();
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
|
||||
mat4 getSkinnedTransform();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* @file avatarEyesV.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
|
||||
varying vec3 vary_normal;
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
||||
|
||||
vary_normal = normalize(gl_NormalMatrix * gl_Normal);
|
||||
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,14 +5,17 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
varying vec4 post_pos;
|
||||
|
||||
void main()
|
||||
{
|
||||
//gl_FragColor = vec4(1,1,1,gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy).a);
|
||||
gl_FragColor = vec4(1,1,1,1);
|
||||
|
||||
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,14 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
mat4 getSkinnedTransform();
|
||||
|
||||
attribute vec4 weight;
|
||||
|
||||
varying vec4 post_pos;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
|
@ -30,8 +32,9 @@ void main()
|
|||
norm = normalize(norm);
|
||||
|
||||
pos = gl_ProjectionMatrix * pos;
|
||||
pos.z = max(pos.z, -pos.w+0.01);
|
||||
gl_Position = pos;
|
||||
post_pos = pos;
|
||||
|
||||
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
|
||||
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
mat4 getSkinnedTransform();
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ uniform vec2 screen_res;
|
|||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
float depth = texture2DRect(depthMap, pos_screen.xy).a;
|
||||
float depth = texture2DRect(depthMap, pos_screen.xy).r;
|
||||
vec2 sc = pos_screen.xy*2.0;
|
||||
sc /= screen_res;
|
||||
sc -= vec2(1.0,1.0);
|
||||
|
|
@ -39,7 +39,7 @@ vec4 getPosition(vec2 pos_screen)
|
|||
|
||||
void main()
|
||||
{
|
||||
vec2 tc = vary_fragcoord.xy;
|
||||
vec2 tc = vary_fragcoord.xy;
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
vec3 pos = getPosition(tc).xyz;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,113 @@
|
|||
/**
|
||||
* @file blurLightF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_texture_multisample : enable
|
||||
|
||||
uniform sampler2DMS depthMap;
|
||||
uniform sampler2DMS normalMap;
|
||||
uniform sampler2DRect lightMap;
|
||||
|
||||
uniform float dist_factor;
|
||||
uniform float blur_size;
|
||||
uniform vec2 delta;
|
||||
uniform vec3 kern[4];
|
||||
uniform float kern_scale;
|
||||
|
||||
varying vec2 vary_fragcoord;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
vec3 texture2DMS3(sampler2DMS tex, ivec2 tc)
|
||||
{
|
||||
vec3 ret = vec3(0,0,0);
|
||||
for (int i = 0; i < samples; i++)
|
||||
{
|
||||
ret += texelFetch(tex, tc, i).rgb;
|
||||
}
|
||||
|
||||
return ret/samples;
|
||||
}
|
||||
|
||||
float texture2DMS1(sampler2DMS tex, ivec2 tc)
|
||||
{
|
||||
float ret = 0;
|
||||
for (int i = 0; i < samples; i++)
|
||||
{
|
||||
ret += texelFetch(tex, tc, i).r;
|
||||
}
|
||||
|
||||
return ret/samples;
|
||||
}
|
||||
|
||||
vec4 getPosition(ivec2 pos_screen)
|
||||
{
|
||||
float depth = texture2DMS1(depthMap, pos_screen.xy);
|
||||
vec2 sc = pos_screen.xy*2.0;
|
||||
sc /= screen_res;
|
||||
sc -= vec2(1.0,1.0);
|
||||
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
|
||||
vec4 pos = inv_proj * ndc;
|
||||
pos /= pos.w;
|
||||
pos.w = 1.0;
|
||||
return pos;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 tc = vary_fragcoord.xy;
|
||||
ivec2 itc = ivec2(tc);
|
||||
|
||||
vec3 norm = texture2DMS3(normalMap, itc).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
vec3 pos = getPosition(itc).xyz;
|
||||
vec4 ccol = texture2DRect(lightMap, tc).rgba;
|
||||
|
||||
vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy);
|
||||
dlt /= max(-pos.z*dist_factor, 1.0);
|
||||
|
||||
vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
|
||||
vec4 col = defined_weight.xyxx * ccol;
|
||||
|
||||
// relax tolerance according to distance to avoid speckling artifacts, as angles and distances are a lot more abrupt within a small screen area at larger distances
|
||||
float pointplanedist_tolerance_pow2 = pos.z*pos.z*0.00005;
|
||||
|
||||
// perturb sampling origin slightly in screen-space to hide edge-ghosting artifacts where smoothing radius is quite large
|
||||
tc += ( (mod(tc.x+tc.y,2) - 0.5) * kern[1].z * dlt * 0.5 );
|
||||
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
vec2 samptc = tc + kern[i].z*dlt;
|
||||
vec3 samppos = getPosition(ivec2(samptc)).xyz;
|
||||
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
|
||||
if (d*d <= pointplanedist_tolerance_pow2)
|
||||
{
|
||||
col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
|
||||
defined_weight += kern[i].xy;
|
||||
}
|
||||
}
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
vec2 samptc = vec2(tc - kern[i].z*dlt);
|
||||
vec3 samppos = getPosition(ivec2(samptc)).xyz;
|
||||
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
|
||||
if (d*d <= pointplanedist_tolerance_pow2)
|
||||
{
|
||||
col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
|
||||
defined_weight += kern[i].xy;
|
||||
}
|
||||
}
|
||||
|
||||
col /= defined_weight.xyxx;
|
||||
col.y *= col.y;
|
||||
|
||||
gl_FragColor = col;
|
||||
}
|
||||
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
varying vec2 vary_fragcoord;
|
||||
uniform vec2 screen_res;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
uniform sampler2D bumpMap;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $License$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
varying vec3 vary_mat0;
|
||||
varying vec3 vary_mat1;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
varying vec3 vary_mat0;
|
||||
varying vec3 vary_mat1;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
/**
|
||||
* @file WLCloudsF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// The fragment shader for the sky
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
varying vec4 vary_CloudColorSun;
|
||||
varying vec4 vary_CloudColorAmbient;
|
||||
varying float vary_CloudDensity;
|
||||
|
||||
uniform sampler2D cloud_noise_texture;
|
||||
uniform vec4 cloud_pos_density1;
|
||||
uniform vec4 cloud_pos_density2;
|
||||
uniform vec4 gamma;
|
||||
|
||||
/// Soft clips the light with a gamma correction
|
||||
vec3 scaleSoftClip(vec3 light) {
|
||||
//soft clip effect:
|
||||
light = 1. - clamp(light, vec3(0.), vec3(1.));
|
||||
light = 1. - pow(light, gamma.xxx);
|
||||
|
||||
return light;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// Set variables
|
||||
vec2 uv1 = gl_TexCoord[0].xy;
|
||||
vec2 uv2 = gl_TexCoord[1].xy;
|
||||
|
||||
vec4 cloudColorSun = vary_CloudColorSun;
|
||||
vec4 cloudColorAmbient = vary_CloudColorAmbient;
|
||||
float cloudDensity = vary_CloudDensity;
|
||||
vec2 uv3 = gl_TexCoord[2].xy;
|
||||
vec2 uv4 = gl_TexCoord[3].xy;
|
||||
|
||||
// Offset texture coords
|
||||
uv1 += cloud_pos_density1.xy; //large texture, visible density
|
||||
uv2 += cloud_pos_density1.xy; //large texture, self shadow
|
||||
uv3 += cloud_pos_density2.xy; //small texture, visible density
|
||||
uv4 += cloud_pos_density2.xy; //small texture, self shadow
|
||||
|
||||
|
||||
// Compute alpha1, the main cloud opacity
|
||||
float alpha1 = (texture2D(cloud_noise_texture, uv1).x - 0.5) + (texture2D(cloud_noise_texture, uv3).x - 0.5) * cloud_pos_density2.z;
|
||||
alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10. * cloud_pos_density1.z, 1.);
|
||||
|
||||
// And smooth
|
||||
alpha1 = 1. - alpha1 * alpha1;
|
||||
alpha1 = 1. - alpha1 * alpha1;
|
||||
|
||||
|
||||
// Compute alpha2, for self shadowing effect
|
||||
// (1 - alpha2) will later be used as percentage of incoming sunlight
|
||||
float alpha2 = (texture2D(cloud_noise_texture, uv2).x - 0.5);
|
||||
alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
|
||||
|
||||
// And smooth
|
||||
alpha2 = 1. - alpha2;
|
||||
alpha2 = 1. - alpha2 * alpha2;
|
||||
|
||||
// Combine
|
||||
vec4 color;
|
||||
color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
|
||||
color *= 2.;
|
||||
|
||||
/// Gamma correct for WL (soft clip effect).
|
||||
gl_FragData[0] = vec4(scaleSoftClip(color.rgb), alpha1);
|
||||
gl_FragData[1] = vec4(0.0,0.0,0.0,0.0);
|
||||
gl_FragData[2] = vec4(0,0,1,0);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
/**
|
||||
* @file WLCloudsV.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// The vertex shader for creating the atmospheric sky
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Output parameters
|
||||
varying vec4 vary_CloudColorSun;
|
||||
varying vec4 vary_CloudColorAmbient;
|
||||
varying float vary_CloudDensity;
|
||||
|
||||
// Inputs
|
||||
uniform vec3 camPosLocal;
|
||||
|
||||
uniform vec4 lightnorm;
|
||||
uniform vec4 sunlight_color;
|
||||
uniform vec4 ambient;
|
||||
uniform vec4 blue_horizon;
|
||||
uniform vec4 blue_density;
|
||||
uniform vec4 haze_horizon;
|
||||
uniform vec4 haze_density;
|
||||
|
||||
uniform vec4 cloud_shadow;
|
||||
uniform vec4 density_multiplier;
|
||||
uniform vec4 max_y;
|
||||
|
||||
uniform vec4 glow;
|
||||
|
||||
uniform vec4 cloud_color;
|
||||
|
||||
uniform vec4 cloud_scale;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
// World / view / projection
|
||||
gl_Position = ftransform();
|
||||
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
||||
// Get relative position
|
||||
vec3 P = gl_Vertex.xyz - camPosLocal.xyz + vec3(0,50,0);
|
||||
|
||||
// Set altitude
|
||||
if (P.y > 0.)
|
||||
{
|
||||
P *= (max_y.x / P.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
P *= (-32000. / P.y);
|
||||
}
|
||||
|
||||
// Can normalize then
|
||||
vec3 Pn = normalize(P);
|
||||
float Plen = length(P);
|
||||
|
||||
// Initialize temp variables
|
||||
vec4 temp1 = vec4(0.);
|
||||
vec4 temp2 = vec4(0.);
|
||||
vec4 blue_weight;
|
||||
vec4 haze_weight;
|
||||
vec4 sunlight = sunlight_color;
|
||||
vec4 light_atten;
|
||||
|
||||
|
||||
// Sunlight attenuation effect (hue and brightness) due to atmosphere
|
||||
// this is used later for sunlight modulation at various altitudes
|
||||
light_atten = (blue_density * 1.0 + haze_density.x * 0.25) * (density_multiplier.x * max_y.x);
|
||||
|
||||
// Calculate relative weights
|
||||
temp1 = blue_density + haze_density.x;
|
||||
blue_weight = blue_density / temp1;
|
||||
haze_weight = haze_density.x / temp1;
|
||||
|
||||
// Compute sunlight from P & lightnorm (for long rays like sky)
|
||||
temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y );
|
||||
temp2.y = 1. / temp2.y;
|
||||
sunlight *= exp( - light_atten * temp2.y);
|
||||
|
||||
// Distance
|
||||
temp2.z = Plen * density_multiplier.x;
|
||||
|
||||
// Transparency (-> temp1)
|
||||
// ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati
|
||||
// compiler gets confused.
|
||||
temp1 = exp(-temp1 * temp2.z);
|
||||
|
||||
|
||||
// Compute haze glow
|
||||
temp2.x = dot(Pn, lightnorm.xyz);
|
||||
temp2.x = 1. - temp2.x;
|
||||
// temp2.x is 0 at the sun and increases away from sun
|
||||
temp2.x = max(temp2.x, .001);
|
||||
// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
|
||||
temp2.x *= glow.x;
|
||||
// Higher glow.x gives dimmer glow (because next step is 1 / "angle")
|
||||
temp2.x = pow(temp2.x, glow.z);
|
||||
// glow.z should be negative, so we're doing a sort of (1 / "angle") function
|
||||
|
||||
// Add "minimum anti-solar illumination"
|
||||
temp2.x += .25;
|
||||
|
||||
// Increase ambient when there are more clouds
|
||||
vec4 tmpAmbient = ambient;
|
||||
tmpAmbient += (1. - tmpAmbient) * cloud_shadow.x * 0.5;
|
||||
|
||||
// Dim sunlight by cloud shadow percentage
|
||||
sunlight *= (1. - cloud_shadow.x);
|
||||
|
||||
// Haze color below cloud
|
||||
vec4 additiveColorBelowCloud = ( blue_horizon * blue_weight * (sunlight + tmpAmbient)
|
||||
+ (haze_horizon.r * haze_weight) * (sunlight * temp2.x + tmpAmbient)
|
||||
);
|
||||
|
||||
// CLOUDS
|
||||
|
||||
sunlight = sunlight_color;
|
||||
temp2.y = max(0., lightnorm.y * 2.);
|
||||
temp2.y = 1. / temp2.y;
|
||||
sunlight *= exp( - light_atten * temp2.y);
|
||||
|
||||
// Cloud color out
|
||||
vary_CloudColorSun = (sunlight * temp2.x) * cloud_color;
|
||||
vary_CloudColorAmbient = tmpAmbient * cloud_color;
|
||||
|
||||
// Attenuate cloud color by atmosphere
|
||||
temp1 = sqrt(temp1); //less atmos opacity (more transparency) below clouds
|
||||
vary_CloudColorSun *= temp1;
|
||||
vary_CloudColorAmbient *= temp1;
|
||||
vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - temp1);
|
||||
|
||||
// Make a nice cloud density based on the cloud_shadow value that was passed in.
|
||||
vary_CloudDensity = 2. * (cloud_shadow.x - 0.25);
|
||||
|
||||
|
||||
// Texture coords
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_TexCoord[0].xy -= 0.5;
|
||||
gl_TexCoord[0].xy /= cloud_scale.x;
|
||||
gl_TexCoord[0].xy += 0.5;
|
||||
|
||||
gl_TexCoord[1] = gl_TexCoord[0];
|
||||
gl_TexCoord[1].x += lightnorm.x * 0.0125;
|
||||
gl_TexCoord[1].y += lightnorm.z * 0.0125;
|
||||
|
||||
gl_TexCoord[2] = gl_TexCoord[0] * 16.;
|
||||
gl_TexCoord[3] = gl_TexCoord[1] * 16.;
|
||||
|
||||
// Combine these to minimize register use
|
||||
vary_CloudColorAmbient += oHazeColorBelowCloud;
|
||||
|
||||
// needs this to compile on mac
|
||||
//vary_AtmosAttenuation = vec3(0.0,0.0,0.0);
|
||||
|
||||
// END CLOUDS
|
||||
}
|
||||
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
|
|
@ -20,3 +20,4 @@ void main()
|
|||
vec3 nvn = normalize(vary_normal);
|
||||
gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* @file diffuseIndexedF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
varying vec3 vary_normal;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 col = gl_Color.rgb * diffuseLookup(gl_TexCoord[0].xy).rgb;
|
||||
|
||||
gl_FragData[0] = vec4(col, 0.0);
|
||||
gl_FragData[1] = gl_Color.aaaa; // spec
|
||||
//gl_FragData[1] = vec4(vec3(gl_Color.a), gl_Color.a+(1.0-gl_Color.a)*gl_Color.a); // spec - from former class3 - maybe better, but not so well tested
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
* $License$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
varying vec3 vary_normal;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,16 +5,18 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
varying vec3 vary_normal;
|
||||
varying float vary_texture_index;
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz, 1.0);
|
||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
||||
|
||||
vary_texture_index = gl_Vertex.w;
|
||||
vary_normal = normalize(gl_NormalMatrix * gl_Normal);
|
||||
|
||||
gl_FrontColor = gl_Color;
|
||||
|
|
|
|||
|
|
@ -5,60 +5,24 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
uniform sampler2DRect depthMap;
|
||||
uniform sampler2D noiseMap;
|
||||
|
||||
uniform vec4 shadow_clip;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
vec3 fullbrightAtmosTransport(vec3 light);
|
||||
vec3 fullbrightScaleSoftClip(vec3 light);
|
||||
|
||||
varying vec3 vary_ambient;
|
||||
varying vec3 vary_directional;
|
||||
varying vec4 vary_position;
|
||||
varying vec3 vary_normal;
|
||||
varying vec3 vary_fragcoord;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
float depth = texture2DRect(depthMap, pos_screen.xy).a;
|
||||
vec2 sc = pos_screen.xy*2.0;
|
||||
sc /= screen_res;
|
||||
sc -= vec2(1.0,1.0);
|
||||
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
|
||||
vec4 pos = inv_proj * ndc;
|
||||
pos /= pos.w;
|
||||
pos.w = 1.0;
|
||||
return pos;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
|
||||
frag *= screen_res;
|
||||
|
||||
vec3 samp_pos = getPosition(frag).xyz;
|
||||
|
||||
float shadow = 1.0;
|
||||
vec4 pos = vary_position;
|
||||
|
||||
vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy)*gl_Color;
|
||||
vec4 color = diffuseLookup(gl_TexCoord[0].xy)*gl_Color;
|
||||
|
||||
color.rgb = fullbrightAtmosTransport(color.rgb);
|
||||
|
||||
color.rgb = fullbrightScaleSoftClip(color.rgb);
|
||||
|
||||
//gl_FragColor = gl_Color;
|
||||
gl_FragColor = color;
|
||||
//gl_FragColor = vec4(1,0,1,1);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
void calcAtmospherics(vec3 inPositionEye);
|
||||
|
||||
|
|
@ -14,30 +14,23 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);
|
|||
vec3 scaleDownLight(vec3 light);
|
||||
vec3 scaleUpLight(vec3 light);
|
||||
|
||||
varying vec3 vary_ambient;
|
||||
varying vec3 vary_directional;
|
||||
varying vec3 vary_normal;
|
||||
varying vec3 vary_fragcoord;
|
||||
uniform float near_clip;
|
||||
varying vec4 vary_position;
|
||||
varying float vary_texture_index;
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = ftransform();
|
||||
vec4 vert = vec4(gl_Vertex.xyz, 1.0);
|
||||
vary_texture_index = gl_Vertex.w;
|
||||
|
||||
gl_Position = gl_ModelViewProjectionMatrix*vert;
|
||||
|
||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
||||
|
||||
vec4 pos = (gl_ModelViewMatrix * gl_Vertex);
|
||||
vary_position = pos;
|
||||
|
||||
vec4 pos = (gl_ModelViewMatrix * vert);
|
||||
|
||||
calcAtmospherics(pos.xyz);
|
||||
|
||||
gl_FrontColor = gl_Color;
|
||||
|
||||
gl_FogFragCoord = pos.z;
|
||||
|
||||
pos = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
varying vec2 vary_fragcoord;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
uniform sampler2D normalMap;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
uniform sampler2DRect diffuseMap;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
|
||||
varying vec2 vary_fragcoord;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ uniform mat4 inv_proj;
|
|||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
float depth = texture2DRect(depthMap, pos_screen.xy).a;
|
||||
float depth = texture2DRect(depthMap, pos_screen.xy).r;
|
||||
vec2 sc = pos_screen.xy*2.0;
|
||||
sc /= screen_res;
|
||||
sc -= vec2(1.0,1.0);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,137 @@
|
|||
/**
|
||||
* @file multiPointLightF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_texture_multisample : enable
|
||||
|
||||
uniform sampler2DMS depthMap;
|
||||
uniform sampler2DMS diffuseRect;
|
||||
uniform sampler2DMS specularRect;
|
||||
uniform sampler2DMS normalMap;
|
||||
uniform sampler2D noiseMap;
|
||||
uniform sampler2D lightFunc;
|
||||
|
||||
|
||||
uniform vec3 env_mat[3];
|
||||
uniform float sun_wash;
|
||||
|
||||
uniform int light_count;
|
||||
|
||||
#define MAX_LIGHT_COUNT 16
|
||||
uniform vec4 light[MAX_LIGHT_COUNT];
|
||||
uniform vec4 light_col[MAX_LIGHT_COUNT];
|
||||
|
||||
varying vec4 vary_fragcoord;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
uniform float far_z;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
vec4 getPosition(ivec2 pos_screen, int sample)
|
||||
{
|
||||
float depth = texelFetch(depthMap, pos_screen, sample).r;
|
||||
vec2 sc = vec2(pos_screen.xy)*2.0;
|
||||
sc /= screen_res;
|
||||
sc -= vec2(1.0,1.0);
|
||||
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
|
||||
vec4 pos = inv_proj * ndc;
|
||||
pos /= pos.w;
|
||||
pos.w = 1.0;
|
||||
return pos;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res;
|
||||
ivec2 itc = ivec2(frag);
|
||||
|
||||
int wght = 0;
|
||||
vec3 fcol = vec3(0,0,0);
|
||||
|
||||
for (int s = 0; s < samples; ++s)
|
||||
{
|
||||
vec3 pos = getPosition(itc, s).xyz;
|
||||
if (pos.z >= far_z)
|
||||
{
|
||||
vec3 norm = texelFetch(normalMap, itc, s).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
norm = normalize(norm);
|
||||
vec4 spec = texelFetch(specularRect, itc, s);
|
||||
vec3 diff = texelFetch(diffuseRect, itc, s).rgb;
|
||||
float noise = texture2D(noiseMap, frag.xy/128.0).b;
|
||||
vec3 out_col = vec3(0,0,0);
|
||||
vec3 npos = normalize(-pos);
|
||||
|
||||
// As of OSX 10.6.7 ATI Apple's crash when using a variable size loop
|
||||
for (int i = 0; i < MAX_LIGHT_COUNT; ++i)
|
||||
{
|
||||
bool light_contrib = (i < light_count);
|
||||
|
||||
vec3 lv = light[i].xyz-pos;
|
||||
float dist2 = dot(lv,lv);
|
||||
dist2 /= light[i].w;
|
||||
if (dist2 > 1.0)
|
||||
{
|
||||
light_contrib = false;
|
||||
}
|
||||
|
||||
float da = dot(norm, lv);
|
||||
if (da < 0.0)
|
||||
{
|
||||
light_contrib = false;
|
||||
}
|
||||
|
||||
if (light_contrib)
|
||||
{
|
||||
lv = normalize(lv);
|
||||
da = dot(norm, lv);
|
||||
|
||||
float fa = light_col[i].a+1.0;
|
||||
float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
dist_atten *= noise;
|
||||
|
||||
float lit = da * dist_atten;
|
||||
|
||||
vec3 col = light_col[i].rgb*lit*diff;
|
||||
//vec3 col = vec3(dist2, light_col[i].a, lit);
|
||||
|
||||
if (spec.a > 0.0)
|
||||
{
|
||||
//vec3 ref = dot(pos+lv, norm);
|
||||
|
||||
float sa = dot(normalize(lv+npos),norm);
|
||||
|
||||
if (sa > 0.0)
|
||||
{
|
||||
sa = texture2D(lightFunc,vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0);
|
||||
sa *= noise;
|
||||
col += da*sa*light_col[i].rgb*spec.rgb;
|
||||
}
|
||||
}
|
||||
|
||||
out_col += col;
|
||||
}
|
||||
}
|
||||
|
||||
fcol += out_col;
|
||||
++wght;
|
||||
}
|
||||
}
|
||||
|
||||
if (wght <= 0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
gl_FragColor.rgb = fcol/samples;
|
||||
gl_FragColor.a = 0.0;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
varying vec4 vary_fragcoord;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
//class 1 -- no shadows
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,232 @@
|
|||
/**
|
||||
* @file multiSpotLightF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//class 1 -- no shadows
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_texture_multisample : enable
|
||||
|
||||
uniform sampler2DMS diffuseRect;
|
||||
uniform sampler2DMS specularRect;
|
||||
uniform sampler2DMS depthMap;
|
||||
uniform sampler2DMS normalMap;
|
||||
uniform sampler2D noiseMap;
|
||||
uniform sampler2D lightFunc;
|
||||
uniform sampler2D projectionMap;
|
||||
|
||||
uniform mat4 proj_mat; //screen space to light space
|
||||
uniform float proj_near; //near clip for projection
|
||||
uniform vec3 proj_p; //plane projection is emitting from (in screen space)
|
||||
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 float shadow_fade;
|
||||
|
||||
varying vec4 vary_light;
|
||||
|
||||
varying vec4 vary_fragcoord;
|
||||
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(ivec2 pos_screen, int sample)
|
||||
{
|
||||
float depth = texelFetch(depthMap, pos_screen, sample).r;
|
||||
vec2 sc = vec2(pos_screen.xy)*2.0;
|
||||
sc /= screen_res;
|
||||
sc -= vec2(1.0,1.0);
|
||||
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
|
||||
vec4 pos = inv_proj * ndc;
|
||||
pos /= pos.w;
|
||||
pos.w = 1.0;
|
||||
return pos;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
int wght = 0;
|
||||
|
||||
vec3 fcol = vec3(0,0,0);
|
||||
|
||||
vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res;
|
||||
|
||||
ivec2 itc = ivec2(frag.xy);
|
||||
|
||||
for (int i = 0; i < samples; ++i)
|
||||
{
|
||||
vec3 pos = getPosition(itc, i).xyz;
|
||||
vec3 lv = vary_light.xyz-pos.xyz;
|
||||
float dist2 = dot(lv,lv);
|
||||
dist2 /= vary_light.w;
|
||||
if (dist2 <= 1.0)
|
||||
{
|
||||
vec3 norm = texelFetch(normalMap, itc, i).xyz*2.0-1.0;
|
||||
|
||||
norm = normalize(norm);
|
||||
float l_dist = -dot(lv, proj_n);
|
||||
|
||||
vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
|
||||
if (proj_tc.z >= 0.0)
|
||||
{
|
||||
proj_tc.xyz /= proj_tc.w;
|
||||
|
||||
float fa = gl_Color.a+1.0;
|
||||
float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
|
||||
if (dist_atten > 0.0)
|
||||
{
|
||||
lv = proj_origin-pos.xyz;
|
||||
lv = normalize(lv);
|
||||
float da = dot(norm, lv);
|
||||
|
||||
vec3 col = vec3(0,0,0);
|
||||
|
||||
vec3 diff_tex = texelFetch(diffuseRect, itc, i).rgb;
|
||||
|
||||
float noise = texture2D(noiseMap, frag.xy/128.0).b;
|
||||
if (proj_tc.z > 0.0 &&
|
||||
proj_tc.x < 1.0 &&
|
||||
proj_tc.y < 1.0 &&
|
||||
proj_tc.x > 0.0 &&
|
||||
proj_tc.y > 0.0)
|
||||
{
|
||||
float lit = 0.0;
|
||||
float amb_da = proj_ambiance;
|
||||
|
||||
if (da > 0.0)
|
||||
{
|
||||
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
|
||||
float lod = diff * proj_lod;
|
||||
|
||||
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
|
||||
|
||||
vec3 lcol = 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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
vec4 spec = texelFetch(specularRect, itc, i);
|
||||
if (spec.a > 0.0)
|
||||
{
|
||||
vec3 ref = reflect(normalize(pos), norm);
|
||||
|
||||
//project from point pos in direction ref to plane proj_p, proj_n
|
||||
vec3 pdelta = proj_p-pos;
|
||||
float ds = dot(ref, proj_n);
|
||||
|
||||
if (ds < 0.0)
|
||||
{
|
||||
vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
|
||||
|
||||
vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
|
||||
|
||||
if (stc.z > 0.0)
|
||||
{
|
||||
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 = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
|
||||
col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fcol += col;
|
||||
++wght;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wght <= 0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
gl_FragColor.rgb = fcol/samples;
|
||||
gl_FragColor.a = 0.0;
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ uniform vec4 viewport;
|
|||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
float depth = texture2DRect(depthMap, pos_screen.xy).a;
|
||||
float depth = texture2DRect(depthMap, pos_screen.xy).r;
|
||||
vec2 sc = (pos_screen.xy-viewport.xy)*2.0;
|
||||
sc /= viewport.zw;
|
||||
sc -= vec2(1.0,1.0);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,108 @@
|
|||
/**
|
||||
* @file pointLightF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_texture_multisample : enable
|
||||
|
||||
uniform sampler2DMS depthMap;
|
||||
uniform sampler2DMS diffuseRect;
|
||||
uniform sampler2DMS specularRect;
|
||||
uniform sampler2DMS normalMap;
|
||||
uniform sampler2D noiseMap;
|
||||
uniform sampler2D lightFunc;
|
||||
|
||||
|
||||
uniform vec3 env_mat[3];
|
||||
uniform float sun_wash;
|
||||
|
||||
varying vec4 vary_light;
|
||||
|
||||
varying vec4 vary_fragcoord;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
uniform vec4 viewport;
|
||||
|
||||
vec4 getPosition(ivec2 pos_screen, int sample)
|
||||
{
|
||||
float depth = texelFetch(depthMap, pos_screen, sample).r;
|
||||
vec2 sc = (vec2(pos_screen.xy)-viewport.xy)*2.0;
|
||||
sc /= viewport.zw;
|
||||
sc -= vec2(1.0,1.0);
|
||||
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
|
||||
vec4 pos = inv_proj * ndc;
|
||||
pos /= pos.w;
|
||||
pos.w = 1.0;
|
||||
return pos;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 frag = vary_fragcoord;
|
||||
frag.xyz /= frag.w;
|
||||
frag.xyz = frag.xyz*0.5+0.5;
|
||||
frag.xy *= screen_res;
|
||||
|
||||
ivec2 itc = ivec2(frag.xy);
|
||||
|
||||
int wght = 0;
|
||||
vec3 fcol = vec3(0,0,0);
|
||||
|
||||
for (int s = 0; s < samples; ++s)
|
||||
{
|
||||
vec3 pos = getPosition(itc, s).xyz;
|
||||
vec3 lv = vary_light.xyz-pos;
|
||||
float dist2 = dot(lv,lv);
|
||||
dist2 /= vary_light.w;
|
||||
if (dist2 <= 1.0)
|
||||
{
|
||||
vec3 norm = texelFetch(normalMap, itc, s).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
float da = dot(norm, lv);
|
||||
if (da >= 0.0)
|
||||
{
|
||||
norm = normalize(norm);
|
||||
lv = normalize(lv);
|
||||
da = dot(norm, lv);
|
||||
|
||||
float noise = texture2D(noiseMap, frag.xy/128.0).b;
|
||||
|
||||
vec3 col = texelFetch(diffuseRect, itc, s).rgb;
|
||||
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 lit = da * dist_atten * noise;
|
||||
|
||||
col = gl_Color.rgb*lit*col;
|
||||
|
||||
vec4 spec = texelFetch(specularRect, itc, s);
|
||||
if (spec.a > 0.0)
|
||||
{
|
||||
float sa = dot(normalize(lv-normalize(pos)),norm);
|
||||
if (sa > 0.0)
|
||||
{
|
||||
sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0);
|
||||
sa *= noise;
|
||||
col += da*sa*gl_Color.rgb*spec.rgb;
|
||||
}
|
||||
}
|
||||
|
||||
fcol += col;
|
||||
++wght;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wght <= 0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
gl_FragColor.rgb = fcol/samples;
|
||||
gl_FragColor.a = 0.0;
|
||||
}
|
||||
|
|
@ -5,19 +5,14 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
varying vec4 vary_light;
|
||||
varying vec4 vary_fragcoord;
|
||||
|
||||
uniform vec2 screen_res;
|
||||
uniform float near_clip;
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
|
||||
vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
vary_fragcoord = pos;
|
||||
|
||||
|
|
@ -25,6 +20,8 @@ void main()
|
|||
tex.w = 1.0;
|
||||
|
||||
vary_light = gl_MultiTexCoord0;
|
||||
|
||||
gl_Position = pos;
|
||||
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ varying vec2 vary_fragcoord;
|
|||
|
||||
float getDepth(vec2 pos_screen)
|
||||
{
|
||||
float z = texture2DRect(depthMap, pos_screen.xy).a;
|
||||
float z = texture2DRect(depthMap, pos_screen.xy).r;
|
||||
z = z*2.0-1.0;
|
||||
vec4 ndc = vec4(0.0, 0.0, z, 1.0);
|
||||
vec4 p = inv_proj*ndc;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,133 @@
|
|||
/**
|
||||
* @file postDeferredF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_texture_multisample : enable
|
||||
|
||||
uniform sampler2DMS diffuseRect;
|
||||
uniform sampler2DMS edgeMap;
|
||||
uniform sampler2DMS depthMap;
|
||||
uniform sampler2DMS normalMap;
|
||||
uniform sampler2D bloomMap;
|
||||
|
||||
uniform float depth_cutoff;
|
||||
uniform float norm_cutoff;
|
||||
uniform float focal_distance;
|
||||
uniform float blur_constant;
|
||||
uniform float tan_pixel_angle;
|
||||
uniform float magnification;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
varying vec2 vary_fragcoord;
|
||||
|
||||
vec4 texture2DMS(sampler2DMS tex, ivec2 tc)
|
||||
{
|
||||
vec4 ret = vec4(0,0,0,0);
|
||||
for (int i = 0; i < samples; ++i)
|
||||
{
|
||||
ret += texelFetch(tex, tc, i);
|
||||
}
|
||||
|
||||
return ret/samples;
|
||||
}
|
||||
|
||||
float getDepth(ivec2 pos_screen)
|
||||
{
|
||||
float z = texture2DMS(depthMap, pos_screen.xy).r;
|
||||
z = z*2.0-1.0;
|
||||
vec4 ndc = vec4(0.0, 0.0, z, 1.0);
|
||||
vec4 p = inv_proj*ndc;
|
||||
return p.z/p.w;
|
||||
}
|
||||
|
||||
float calc_cof(float depth)
|
||||
{
|
||||
float sc = abs(depth-focal_distance)/-depth*blur_constant;
|
||||
|
||||
sc /= magnification;
|
||||
|
||||
// tan_pixel_angle = pixel_length/-depth;
|
||||
float pixel_length = tan_pixel_angle*-focal_distance;
|
||||
|
||||
sc = sc/pixel_length;
|
||||
sc *= 1.414;
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
void dofSample(inout vec4 diff, inout float w, float min_sc, float cur_depth, ivec2 tc)
|
||||
{
|
||||
float d = getDepth(tc);
|
||||
|
||||
float sc = calc_cof(d);
|
||||
|
||||
if (sc > min_sc //sampled pixel is more "out of focus" than current sample radius
|
||||
|| d < cur_depth) //sampled pixel is further away than current pixel
|
||||
{
|
||||
float wg = 0.25;
|
||||
|
||||
vec4 s = texture2DMS(diffuseRect, tc);
|
||||
// de-weight dull areas to make highlights 'pop'
|
||||
wg += s.r+s.g+s.b;
|
||||
|
||||
diff += wg*s;
|
||||
|
||||
w += wg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 itc = ivec2(vary_fragcoord.xy);
|
||||
|
||||
vec3 norm = texture2DMS(normalMap, itc).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
|
||||
float depth = getDepth(itc);
|
||||
|
||||
vec4 diff = texture2DMS(diffuseRect, itc);
|
||||
|
||||
{
|
||||
float w = 1.0;
|
||||
|
||||
float sc = calc_cof(depth);
|
||||
sc = min(abs(sc), 10.0);
|
||||
|
||||
float fd = depth*0.5f;
|
||||
|
||||
float PI = 3.14159265358979323846264;
|
||||
|
||||
int isc = int(sc);
|
||||
|
||||
// sample quite uniformly spaced points within a circle, for a circular 'bokeh'
|
||||
//if (depth < focal_distance)
|
||||
{
|
||||
for (int x = -isc; x <= isc; x+=2)
|
||||
{
|
||||
for (int y = -isc; y <= isc; y+=2)
|
||||
{
|
||||
ivec2 cur_samp = ivec2(x,y);
|
||||
float cur_sc = length(vec2(cur_samp));
|
||||
if (cur_sc < sc)
|
||||
{
|
||||
dofSample(diff, w, cur_sc, depth, itc+cur_samp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
diff /= w;
|
||||
}
|
||||
|
||||
vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res);
|
||||
gl_FragColor = diff + bloom;
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* @file postDeferredF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_texture_multisample : enable
|
||||
|
||||
uniform sampler2DMS diffuseRect;
|
||||
uniform sampler2D bloomMap;
|
||||
|
||||
uniform vec2 screen_res;
|
||||
varying vec2 vary_fragcoord;
|
||||
|
||||
vec4 texture2DMS(sampler2DMS tex, ivec2 tc)
|
||||
{
|
||||
vec4 ret = vec4(0,0,0,0);
|
||||
|
||||
for (int i = 0; i < samples; ++i)
|
||||
{
|
||||
ret += texelFetch(tex,tc,i);
|
||||
}
|
||||
|
||||
return ret/samples;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 diff = texture2DMS(diffuseRect, ivec2(vary_fragcoord.xy));
|
||||
|
||||
vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res);
|
||||
gl_FragColor = diff + bloom;
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
varying vec2 vary_fragcoord;
|
||||
uniform vec2 screen_res;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
uniform sampler2DRect depthMap;
|
||||
uniform sampler2DRect normalMap;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
varying vec2 vary_fragcoord;
|
||||
uniform vec2 screen_res;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
varying vec4 post_pos;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* @file WLSkyF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// The fragment shader for the sky
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
varying vec4 vary_HazeColor;
|
||||
|
||||
uniform sampler2D cloud_noise_texture;
|
||||
uniform vec4 gamma;
|
||||
|
||||
/// Soft clips the light with a gamma correction
|
||||
vec3 scaleSoftClip(vec3 light) {
|
||||
//soft clip effect:
|
||||
light = 1. - clamp(light, vec3(0.), vec3(1.));
|
||||
light = 1. - pow(light, gamma.xxx);
|
||||
|
||||
return light;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// Potential Fill-rate optimization. Add cloud calculation
|
||||
// back in and output alpha of 0 (so that alpha culling kills
|
||||
// the fragment) if the sky wouldn't show up because the clouds
|
||||
// are fully opaque.
|
||||
|
||||
vec4 color;
|
||||
color = vary_HazeColor;
|
||||
color *= 2.;
|
||||
|
||||
/// Gamma correct for WL (soft clip effect).
|
||||
gl_FragData[0] = vec4(scaleSoftClip(color.rgb), 1.0);
|
||||
gl_FragData[1] = vec4(0.0,0.0,0.0,0.0);
|
||||
gl_FragData[2] = vec4(0,0,1,0);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
/**
|
||||
* @file WLSkyV.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// SKY ////////////////////////////////////////////////////////////////////////
|
||||
// The vertex shader for creating the atmospheric sky
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Output parameters
|
||||
varying vec4 vary_HazeColor;
|
||||
|
||||
// Inputs
|
||||
uniform vec3 camPosLocal;
|
||||
|
||||
uniform vec4 lightnorm;
|
||||
uniform vec4 sunlight_color;
|
||||
uniform vec4 ambient;
|
||||
uniform vec4 blue_horizon;
|
||||
uniform vec4 blue_density;
|
||||
uniform vec4 haze_horizon;
|
||||
uniform vec4 haze_density;
|
||||
|
||||
uniform vec4 cloud_shadow;
|
||||
uniform vec4 density_multiplier;
|
||||
uniform vec4 max_y;
|
||||
|
||||
uniform vec4 glow;
|
||||
|
||||
uniform vec4 cloud_color;
|
||||
|
||||
uniform vec4 cloud_scale;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
// World / view / projection
|
||||
gl_Position = ftransform();
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
||||
// Get relative position
|
||||
vec3 P = gl_Vertex.xyz - camPosLocal.xyz + vec3(0,50,0);
|
||||
//vec3 P = gl_Vertex.xyz + vec3(0,50,0);
|
||||
|
||||
// Set altitude
|
||||
if (P.y > 0.)
|
||||
{
|
||||
P *= (max_y.x / P.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
P *= (-32000. / P.y);
|
||||
}
|
||||
|
||||
// Can normalize then
|
||||
vec3 Pn = normalize(P);
|
||||
float Plen = length(P);
|
||||
|
||||
// Initialize temp variables
|
||||
vec4 temp1 = vec4(0.);
|
||||
vec4 temp2 = vec4(0.);
|
||||
vec4 blue_weight;
|
||||
vec4 haze_weight;
|
||||
vec4 sunlight = sunlight_color;
|
||||
vec4 light_atten;
|
||||
|
||||
|
||||
// Sunlight attenuation effect (hue and brightness) due to atmosphere
|
||||
// this is used later for sunlight modulation at various altitudes
|
||||
light_atten = (blue_density * 1.0 + haze_density.x * 0.25) * (density_multiplier.x * max_y.x);
|
||||
|
||||
// Calculate relative weights
|
||||
temp1 = blue_density + haze_density.x;
|
||||
blue_weight = blue_density / temp1;
|
||||
haze_weight = haze_density.x / temp1;
|
||||
|
||||
// Compute sunlight from P & lightnorm (for long rays like sky)
|
||||
temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y );
|
||||
temp2.y = 1. / temp2.y;
|
||||
sunlight *= exp( - light_atten * temp2.y);
|
||||
|
||||
// Distance
|
||||
temp2.z = Plen * density_multiplier.x;
|
||||
|
||||
// Transparency (-> temp1)
|
||||
// ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati
|
||||
// compiler gets confused.
|
||||
temp1 = exp(-temp1 * temp2.z);
|
||||
|
||||
|
||||
// Compute haze glow
|
||||
temp2.x = dot(Pn, lightnorm.xyz);
|
||||
temp2.x = 1. - temp2.x;
|
||||
// temp2.x is 0 at the sun and increases away from sun
|
||||
temp2.x = max(temp2.x, .001);
|
||||
// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
|
||||
temp2.x *= glow.x;
|
||||
// Higher glow.x gives dimmer glow (because next step is 1 / "angle")
|
||||
temp2.x = pow(temp2.x, glow.z);
|
||||
// glow.z should be negative, so we're doing a sort of (1 / "angle") function
|
||||
|
||||
// Add "minimum anti-solar illumination"
|
||||
temp2.x += .25;
|
||||
|
||||
|
||||
// Haze color above cloud
|
||||
vary_HazeColor = ( blue_horizon * blue_weight * (sunlight + ambient)
|
||||
+ (haze_horizon.r * haze_weight) * (sunlight * temp2.x + ambient)
|
||||
);
|
||||
|
||||
|
||||
// Increase ambient when there are more clouds
|
||||
vec4 tmpAmbient = ambient;
|
||||
tmpAmbient += (1. - tmpAmbient) * cloud_shadow.x * 0.5;
|
||||
|
||||
// Dim sunlight by cloud shadow percentage
|
||||
sunlight *= (1. - cloud_shadow.x);
|
||||
|
||||
// Haze color below cloud
|
||||
vec4 additiveColorBelowCloud = ( blue_horizon * blue_weight * (sunlight + tmpAmbient)
|
||||
+ (haze_horizon.r * haze_weight) * (sunlight * temp2.x + tmpAmbient)
|
||||
);
|
||||
|
||||
// Final atmosphere additive
|
||||
vary_HazeColor *= (1. - temp1);
|
||||
|
||||
// Attenuate cloud color by atmosphere
|
||||
temp1 = sqrt(temp1); //less atmos opacity (more transparency) below clouds
|
||||
|
||||
// At horizon, blend high altitude sky color towards the darker color below the clouds
|
||||
vary_HazeColor += (additiveColorBelowCloud - vary_HazeColor) * (1. - sqrt(temp1));
|
||||
|
||||
// won't compile on mac without this being set
|
||||
//vary_AtmosAttenuation = vec3(0.0,0.0,0.0);
|
||||
}
|
||||
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
|
|
@ -259,7 +259,7 @@ vec3 scaleSoftClip(vec3 light)
|
|||
void main()
|
||||
{
|
||||
vec2 tc = vary_fragcoord.xy;
|
||||
float depth = texture2DRect(depthMap, tc.xy).a;
|
||||
float depth = texture2DRect(depthMap, tc.xy).r;
|
||||
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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,318 @@
|
|||
/**
|
||||
* @file softenLightF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_texture_multisample : enable
|
||||
|
||||
uniform sampler2DMS diffuseRect;
|
||||
uniform sampler2DMS specularRect;
|
||||
uniform sampler2DMS normalMap;
|
||||
uniform sampler2DMS depthMap;
|
||||
uniform sampler2D noiseMap;
|
||||
uniform samplerCube environmentMap;
|
||||
uniform sampler2D lightFunc;
|
||||
|
||||
uniform float blur_size;
|
||||
uniform float blur_fidelity;
|
||||
|
||||
// Inputs
|
||||
uniform vec4 morphFactor;
|
||||
uniform vec3 camPosLocal;
|
||||
//uniform vec4 camPosWorld;
|
||||
uniform vec4 gamma;
|
||||
uniform vec4 lightnorm;
|
||||
uniform vec4 sunlight_color;
|
||||
uniform vec4 ambient;
|
||||
uniform vec4 blue_horizon;
|
||||
uniform vec4 blue_density;
|
||||
uniform vec4 haze_horizon;
|
||||
uniform vec4 haze_density;
|
||||
uniform vec4 cloud_shadow;
|
||||
uniform vec4 density_multiplier;
|
||||
uniform vec4 distance_multiplier;
|
||||
uniform vec4 max_y;
|
||||
uniform vec4 glow;
|
||||
uniform float scene_light_strength;
|
||||
uniform vec3 env_mat[3];
|
||||
//uniform mat4 shadow_matrix[3];
|
||||
//uniform vec4 shadow_clip;
|
||||
uniform mat3 ssao_effect_mat;
|
||||
|
||||
varying vec4 vary_light;
|
||||
varying vec2 vary_fragcoord;
|
||||
|
||||
vec3 vary_PositionEye;
|
||||
|
||||
vec3 vary_SunlitColor;
|
||||
vec3 vary_AmblitColor;
|
||||
vec3 vary_AdditiveColor;
|
||||
vec3 vary_AtmosAttenuation;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
vec4 getPosition_d(vec2 pos_screen, float depth)
|
||||
{
|
||||
vec2 sc = pos_screen.xy*2.0;
|
||||
sc /= screen_res;
|
||||
sc -= vec2(1.0,1.0);
|
||||
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
|
||||
vec4 pos = inv_proj * ndc;
|
||||
pos /= pos.w;
|
||||
pos.w = 1.0;
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec3 getPositionEye()
|
||||
{
|
||||
return vary_PositionEye;
|
||||
}
|
||||
vec3 getSunlitColor()
|
||||
{
|
||||
return vary_SunlitColor;
|
||||
}
|
||||
vec3 getAmblitColor()
|
||||
{
|
||||
return vary_AmblitColor;
|
||||
}
|
||||
vec3 getAdditiveColor()
|
||||
{
|
||||
return vary_AdditiveColor;
|
||||
}
|
||||
vec3 getAtmosAttenuation()
|
||||
{
|
||||
return vary_AtmosAttenuation;
|
||||
}
|
||||
|
||||
|
||||
void setPositionEye(vec3 v)
|
||||
{
|
||||
vary_PositionEye = v;
|
||||
}
|
||||
|
||||
void setSunlitColor(vec3 v)
|
||||
{
|
||||
vary_SunlitColor = v;
|
||||
}
|
||||
|
||||
void setAmblitColor(vec3 v)
|
||||
{
|
||||
vary_AmblitColor = v;
|
||||
}
|
||||
|
||||
void setAdditiveColor(vec3 v)
|
||||
{
|
||||
vary_AdditiveColor = v;
|
||||
}
|
||||
|
||||
void setAtmosAttenuation(vec3 v)
|
||||
{
|
||||
vary_AtmosAttenuation = v;
|
||||
}
|
||||
|
||||
void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
|
||||
|
||||
vec3 P = inPositionEye;
|
||||
setPositionEye(P);
|
||||
|
||||
//(TERRAIN) limit altitude
|
||||
if (P.y > max_y.x) P *= (max_y.x / P.y);
|
||||
if (P.y < -max_y.x) P *= (-max_y.x / P.y);
|
||||
|
||||
vec3 tmpLightnorm = lightnorm.xyz;
|
||||
|
||||
vec3 Pn = normalize(P);
|
||||
float Plen = length(P);
|
||||
|
||||
vec4 temp1 = vec4(0);
|
||||
vec3 temp2 = vec3(0);
|
||||
vec4 blue_weight;
|
||||
vec4 haze_weight;
|
||||
vec4 sunlight = sunlight_color;
|
||||
vec4 light_atten;
|
||||
|
||||
//sunlight attenuation effect (hue and brightness) due to atmosphere
|
||||
//this is used later for sunlight modulation at various altitudes
|
||||
light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x);
|
||||
//I had thought blue_density and haze_density should have equal weighting,
|
||||
//but attenuation due to haze_density tends to seem too strong
|
||||
|
||||
temp1 = blue_density + vec4(haze_density.r);
|
||||
blue_weight = blue_density / temp1;
|
||||
haze_weight = vec4(haze_density.r) / temp1;
|
||||
|
||||
//(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
|
||||
temp2.y = max(0.0, tmpLightnorm.y);
|
||||
temp2.y = 1. / temp2.y;
|
||||
sunlight *= exp( - light_atten * temp2.y);
|
||||
|
||||
// main atmospheric scattering line integral
|
||||
temp2.z = Plen * density_multiplier.x;
|
||||
|
||||
// Transparency (-> temp1)
|
||||
// ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati
|
||||
// compiler gets confused.
|
||||
temp1 = exp(-temp1 * temp2.z * distance_multiplier.x);
|
||||
|
||||
//final atmosphere attenuation factor
|
||||
setAtmosAttenuation(temp1.rgb);
|
||||
|
||||
//compute haze glow
|
||||
//(can use temp2.x as temp because we haven't used it yet)
|
||||
temp2.x = dot(Pn, tmpLightnorm.xyz);
|
||||
temp2.x = 1. - temp2.x;
|
||||
//temp2.x is 0 at the sun and increases away from sun
|
||||
temp2.x = max(temp2.x, .03); //was glow.y
|
||||
//set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
|
||||
temp2.x *= glow.x;
|
||||
//higher glow.x gives dimmer glow (because next step is 1 / "angle")
|
||||
temp2.x = pow(temp2.x, glow.z);
|
||||
//glow.z should be negative, so we're doing a sort of (1 / "angle") function
|
||||
|
||||
//add "minimum anti-solar illumination"
|
||||
temp2.x += .25;
|
||||
|
||||
//increase ambient when there are more clouds
|
||||
vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.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(
|
||||
vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient)
|
||||
+ (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x
|
||||
+ tmpAmbient)));
|
||||
|
||||
//brightness of surface both sunlight and ambient
|
||||
setSunlitColor(vec3(sunlight * .5));
|
||||
setAmblitColor(vec3(tmpAmbient * .25));
|
||||
setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
|
||||
}
|
||||
|
||||
vec3 atmosLighting(vec3 light)
|
||||
{
|
||||
light *= getAtmosAttenuation().r;
|
||||
light += getAdditiveColor();
|
||||
return (2.0 * light);
|
||||
}
|
||||
|
||||
vec3 atmosTransport(vec3 light) {
|
||||
light *= getAtmosAttenuation().r;
|
||||
light += getAdditiveColor() * 2.0;
|
||||
return light;
|
||||
}
|
||||
vec3 atmosGetDiffuseSunlightColor()
|
||||
{
|
||||
return getSunlitColor();
|
||||
}
|
||||
|
||||
vec3 scaleDownLight(vec3 light)
|
||||
{
|
||||
return (light / scene_light_strength );
|
||||
}
|
||||
|
||||
vec3 scaleUpLight(vec3 light)
|
||||
{
|
||||
return (light * scene_light_strength);
|
||||
}
|
||||
|
||||
vec3 atmosAmbient(vec3 light)
|
||||
{
|
||||
return getAmblitColor() + light / 2.0;
|
||||
}
|
||||
|
||||
vec3 atmosAffectDirectionalLight(float lightIntensity)
|
||||
{
|
||||
return getSunlitColor() * lightIntensity;
|
||||
}
|
||||
|
||||
vec3 scaleSoftClip(vec3 light)
|
||||
{
|
||||
//soft clip effect:
|
||||
light = 1. - clamp(light, vec3(0.), vec3(1.));
|
||||
light = 1. - pow(light, gamma.xxx);
|
||||
|
||||
return light;
|
||||
}
|
||||
|
||||
vec4 texture2DMS(sampler2DMS tex, ivec2 tc)
|
||||
{
|
||||
vec4 ret = vec4(0,0,0,0);
|
||||
|
||||
for (int i = 0; i < samples; ++i)
|
||||
{
|
||||
ret += texelFetch(tex,tc,i);
|
||||
}
|
||||
|
||||
return ret/samples;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 tc = vary_fragcoord.xy;
|
||||
ivec2 itc = ivec2(tc);
|
||||
|
||||
vec3 fcol = vec3(0,0,0);
|
||||
|
||||
for (int i = 0; i < samples; ++i)
|
||||
{
|
||||
float depth = texelFetch(depthMap, itc, i).r;
|
||||
vec3 pos = getPosition_d(tc, depth).xyz;
|
||||
vec3 norm = texelFetch(normalMap, itc, i).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);
|
||||
|
||||
vec4 diffuse = texelFetch(diffuseRect, itc, i);
|
||||
if (diffuse.a >= 1.0)
|
||||
{
|
||||
fcol += diffuse.rgb;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec4 spec = texelFetch(specularRect, itc, i);
|
||||
|
||||
calcAtmospherics(pos.xyz, 1.0);
|
||||
|
||||
vec3 col = atmosAmbient(vec3(0));
|
||||
col += atmosAffectDirectionalLight(max(min(da, 1.0), diffuse.a));
|
||||
|
||||
col *= diffuse.rgb;
|
||||
|
||||
if (spec.a > 0.0) // specular reflection
|
||||
{
|
||||
// the old infinite-sky shiny reflection
|
||||
//
|
||||
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
|
||||
float sa = dot(refnormpersp, vary_light.xyz);
|
||||
vec3 dumbshiny = vary_SunlitColor*texture2D(lightFunc, vec2(sa, spec.a)).a;
|
||||
|
||||
// add the two types of shiny together
|
||||
col += dumbshiny * spec.rgb;
|
||||
}
|
||||
|
||||
col = atmosLighting(col);
|
||||
col = scaleSoftClip(col);
|
||||
fcol += col;
|
||||
}
|
||||
}
|
||||
|
||||
gl_FragColor.rgb = fcol.rgb/samples;
|
||||
gl_FragColor.a = 0.0;
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
uniform vec2 screen_res;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,234 @@
|
|||
/**
|
||||
* @file multiSpotLightF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//class 1 -- no shadows
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_texture_multisample : enable
|
||||
|
||||
uniform sampler2DMS diffuseRect;
|
||||
uniform sampler2DMS specularRect;
|
||||
uniform sampler2DMS depthMap;
|
||||
uniform sampler2DMS normalMap;
|
||||
uniform sampler2D noiseMap;
|
||||
uniform sampler2D lightFunc;
|
||||
uniform sampler2D projectionMap;
|
||||
|
||||
uniform mat4 proj_mat; //screen space to light space
|
||||
uniform float proj_near; //near clip for projection
|
||||
uniform vec3 proj_p; //plane projection is emitting from (in screen space)
|
||||
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;
|
||||
|
||||
varying vec4 vary_fragcoord;
|
||||
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(ivec2 pos_screen, int sample)
|
||||
{
|
||||
float depth = texelFetch(depthMap, pos_screen, sample).r;
|
||||
vec2 sc = vec2(pos_screen.xy)*2.0;
|
||||
sc /= screen_res;
|
||||
sc -= vec2(1.0,1.0);
|
||||
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
|
||||
vec4 pos = inv_proj * ndc;
|
||||
pos /= pos.w;
|
||||
pos.w = 1.0;
|
||||
return pos;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 frag = vary_fragcoord;
|
||||
frag.xyz /= frag.w;
|
||||
frag.xyz = frag.xyz*0.5+0.5;
|
||||
frag.xy *= screen_res;
|
||||
ivec2 itc = ivec2(frag.xy);
|
||||
|
||||
vec3 fcol = vec3(0,0,0);
|
||||
int wght = 0;
|
||||
|
||||
for (int i = 0; i < samples; ++i)
|
||||
{
|
||||
vec3 pos = getPosition(itc, i).xyz;
|
||||
vec3 lv = vary_light.xyz-pos.xyz;
|
||||
float dist2 = dot(lv,lv);
|
||||
dist2 /= vary_light.w;
|
||||
if (dist2 <= 1.0)
|
||||
{
|
||||
vec3 norm = texelFetch(normalMap, itc, i).xyz*2.0-1.0;
|
||||
|
||||
norm = normalize(norm);
|
||||
float l_dist = -dot(lv, proj_n);
|
||||
|
||||
vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
|
||||
if (proj_tc.z >= 0.0)
|
||||
{
|
||||
proj_tc.xyz /= proj_tc.w;
|
||||
|
||||
float fa = gl_Color.a+1.0;
|
||||
float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
|
||||
if (dist_atten > 0.0)
|
||||
{
|
||||
lv = proj_origin-pos.xyz;
|
||||
lv = normalize(lv);
|
||||
float da = dot(norm, lv);
|
||||
|
||||
vec3 col = vec3(0,0,0);
|
||||
|
||||
vec3 diff_tex = texelFetch(diffuseRect, itc, i).rgb;
|
||||
|
||||
float noise = texture2D(noiseMap, frag.xy/128.0).b;
|
||||
if (proj_tc.z > 0.0 &&
|
||||
proj_tc.x < 1.0 &&
|
||||
proj_tc.y < 1.0 &&
|
||||
proj_tc.x > 0.0 &&
|
||||
proj_tc.y > 0.0)
|
||||
{
|
||||
float lit = 0.0;
|
||||
float amb_da = proj_ambiance;
|
||||
|
||||
if (da > 0.0)
|
||||
{
|
||||
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
|
||||
float lod = diff * proj_lod;
|
||||
|
||||
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
|
||||
|
||||
vec3 lcol = 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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
vec4 spec = texelFetch(specularRect, itc, i);
|
||||
if (spec.a > 0.0)
|
||||
{
|
||||
vec3 ref = reflect(normalize(pos), norm);
|
||||
|
||||
//project from point pos in direction ref to plane proj_p, proj_n
|
||||
vec3 pdelta = proj_p-pos;
|
||||
float ds = dot(ref, proj_n);
|
||||
|
||||
if (ds < 0.0)
|
||||
{
|
||||
vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
|
||||
|
||||
vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
|
||||
|
||||
if (stc.z > 0.0)
|
||||
{
|
||||
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 = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
|
||||
col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fcol += col;
|
||||
++wght;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wght <= 0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
gl_FragColor.rgb = fcol/samples;
|
||||
gl_FragColor.a = 0.0;
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* @file starsF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 col = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy);
|
||||
|
||||
gl_FragData[0] = col;
|
||||
gl_FragData[1] = vec4(0,0,0,0);
|
||||
gl_FragData[2] = vec4(0,0,1,0);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue