diff options
311 files changed, 8796 insertions, 2851 deletions
diff --git a/BuildParams b/BuildParams index c303bd2e5e..f34b262913 100644 --- a/BuildParams +++ b/BuildParams @@ -103,6 +103,16 @@ 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  # ======================================== diff --git a/autobuild.xml b/autobuild.xml index ec52d6e331..3cccddf861 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -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> diff --git a/indra/llcommon/llaccountingquota.h b/indra/llcommon/llaccountingquota.h index 3401cb57b6..140333de07 100644 --- a/indra/llcommon/llaccountingquota.h +++ b/indra/llcommon/llaccountingquota.h @@ -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 diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index 5be5ecc492..bf62600514 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -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; diff --git a/indra/llcommon/llstat.cpp b/indra/llcommon/llstat.cpp index 8ba97d7730..b2c495d093 100644 --- a/indra/llcommon/llstat.cpp +++ b/indra/llcommon/llstat.cpp @@ -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;  		}  	}	 diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index fdfc24f8b7..e5ca47da69 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -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) diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index c504215ee5..8c81f27784 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -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; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 01bfbd858b..f67f8f644d 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -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; diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index 5d03615e53..6133f50637 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -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"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index 8dc86601e6..f94ee1ed22 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -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; diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 57ac7a143f..0463d5364b 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -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")); -	}  } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 23f4b5cb42..cd9f76fcb7 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -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); diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index a460912e70..a3aed4dd8a 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -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) +			if (stackDepth != 1)  			{ -				gFailLog << "Texture matrix stack corrupted." << std::endl; +				error = TRUE; +				LL_WARNS("RenderState") << "Texture matrix stack corrupted." << LL_ENDL; + +				if (gDebugSession) +				{ +					gFailLog << "Texture matrix stack corrupted." << std::endl; +				}  			} -		} -		glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) mat.m); -		stop_glerror(); +			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) +			if (mat != identity)  			{ -				gFailLog << "Texture matrix in channel " << i << " corrupt." << std::endl; +				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();  			} -		} -		 -		for (S32 j = (i == 0 ? 1 : 0);  -			j < (gGLManager.mHasTextureRectangle ? 9 : 8); j++) -		{ -			if (glIsEnabled(value[j])) +			glGetFloatv(GL_TEXTURE_MATRIX, mat.m); +			stop_glerror(); + +			if (mat != identity)  			{  				error = TRUE; -				LL_WARNS("RenderState") << "Texture channel " << i << " still has " << label[j] << " enabled." << LL_ENDL; +				LL_WARNS("RenderState") << "Texture matrix " << i << " is not identity." << LL_ENDL;  				if (gDebugSession)  				{ -					gFailLog << "Texture channel " << i << " still has " << label[j] << " enabled." << std::endl; +					gFailLog << "Texture matrix " << i << " is not identity." << 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) +			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(); diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 1d7ab188fc..d1bee00161 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -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; diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index d8140a124d..f35f329f00 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -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 diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 257bcd9380..8e99f62de6 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -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) diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index d46ddbbe18..4922eb6d67 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -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); diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index d408077c68..60a5962234 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -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();  			}  		} diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 6c980984c0..2cfb15b0d9 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -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() ; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index c37139ac4c..6a3f186531 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -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(); diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 7ba14f7b40..41e7b35341 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -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; diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index da1e94df64..b6463309e1 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -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); - -	stop_glerror(); -	if (offset == 0) +#ifdef GL_ARB_texture_multisample +	if (mSamples > 1)  	{ -		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); +		glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, color_fmt, mResX, mResY, GL_TRUE);  	}  	else -	{ //don't filter data attachments -		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); -	} -	if (mUsage != LLTexUnit::TT_RECT_TEXTURE) +#else +	llassert_always(mSamples <= 1); +#endif  	{ -		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR); +		LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL);  	} -	else -	{ -		// ATI doesn't support mirrored repeat for rectangular textures. -		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); +	 +	stop_glerror(); + +	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); -			} +		if (mTex.empty()) +		{ //no color buffer to draw to +			glDrawBuffer(GL_NONE); +			glReadBuffer(GL_NONE); +		} -			check_framebuffer_status(); +		check_framebuffer_status(); -			stop_glerror(); -		} +		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);	 -	} -} - diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index 12dd1c8b90..094b58b562 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -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 diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 98a0a93084..e51ef8cfe7 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -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;  			}  		}  	} @@ -320,7 +408,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)  	}  } -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,73 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  	GLcharARB* text[1024];  	GLuint count = 0; +	//set version to 1.20 +	text[count++] = strdup("#version 120\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"); +		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"); +		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 +612,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;	  	} diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index c54c4608d7..2f30103811 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -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 diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 8c9171ccf4..4a0b964e61 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -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(); - -			//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 (!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; + +				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 << "glMapBuffer returned NULL (no vertex data)" << llendl; +				} +				else  				{ -					llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; +					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) -{ -	return VertexBufferStrider<LLVector3,TYPE_VERTEX>::get(*this, strider, index); -} -bool LLVertexBuffer::getIndexStrider(LLStrider<U16>& strider, S32 index) +bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)  { -	return VertexBufferStrider<U16,TYPE_INDEX>::get(*this, strider, index); +	return VertexBufferStrider<LLVector3,TYPE_VERTEX>::get(*this, strider, index, count, map_range);  } -bool LLVertexBuffer::getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index) +bool LLVertexBuffer::getIndexStrider(LLStrider<U16>& strider, S32 index, S32 count, bool map_range)  { -	return VertexBufferStrider<LLVector2,TYPE_TEXCOORD0>::get(*this, strider, index); +	return VertexBufferStrider<U16,TYPE_INDEX>::get(*this, strider, index, count, map_range);  } -bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index) +bool LLVertexBuffer::getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index, S32 count, bool map_range)  { -	return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index); +	return VertexBufferStrider<LLVector2,TYPE_TEXCOORD0>::get(*this, strider, index, count, map_range);  } -/*bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index) +bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index, S32 count, bool map_range)  { -	return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index); +	return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index, count, map_range);  } -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) + +bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)  { -	return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index); +	return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count, map_range);  } -bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index) +bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)  { -	return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index); +	return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index, count, map_range);  } -bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index) +bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index, S32 count, bool map_range)  { -	return VertexBufferStrider<LLColor4U,TYPE_COLOR>::get(*this, strider, index); +	return VertexBufferStrider<LLColor4U,TYPE_COLOR>::get(*this, strider, index, count, map_range);  } -bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, S32 index) +bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, S32 index, S32 count, bool map_range)  { -	return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index); +	return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index, count, map_range);  } -bool LLVertexBuffer::getWeight4Strider(LLStrider<LLVector4>& strider, S32 index) +bool LLVertexBuffer::getWeight4Strider(LLStrider<LLVector4>& strider, S32 index, S32 count, bool map_range)  { -	return VertexBufferStrider<LLVector4,TYPE_WEIGHT4>::get(*this, strider, index); +	return VertexBufferStrider<LLVector4,TYPE_WEIGHT4>::get(*this, strider, index, count, map_range);  } -bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index) +bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index, S32 count, bool map_range)  { -	return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index); +	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) -	{ -	 -	}*/ -} diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index a9f22193f8..aa5df305a6 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -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; diff --git a/indra/llui/llresmgr.cpp b/indra/llui/llresmgr.cpp index 39385786bc..820e7cb26a 100644 --- a/indra/llui/llresmgr.cpp +++ b/indra/llui/llresmgr.cpp @@ -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 diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index 6b4e9cf923..15a7438ec9 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -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()); diff --git a/indra/llui/llspinctrl.h b/indra/llui/llspinctrl.h index 8960971594..d197084e38 100644 --- a/indra/llui/llspinctrl.h +++ b/indra/llui/llspinctrl.h @@ -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; diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index 937c4e4c6a..9f4e89691f 100644 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -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> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ac6ea0f860..76fecdf05e 100644..100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -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> @@ -8942,7 +9033,7 @@        <key>Type</key>        <string>Boolean</string>        <key>Value</key> -      <integer>1</integer> +      <integer>0</integer>      </map>    <key>RenderUseStreamVBO</key>    <map> @@ -9052,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> diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl index 3f6b8b3323..b0fa0ddd3e 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  void default_lighting(); diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl index 1ad87badfe..d9f29ced4f 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  attribute vec4 weight;  //1 diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl index a15846f192..2796222c68 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);  mat4 getSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl b/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl index 05fe100372..d86ef19a04 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  void default_lighting(); diff --git a/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl b/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl index 4b8a7604a1..2eb814bd91 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol);  void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl index ef823c28b1..7613e50dca 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl @@ -5,7 +5,7 @@   * $License$   */ -#version 120 +  attribute vec4 object_weight;   diff --git a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl index 27ac59a840..2638351e96 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl index f1aa549a47..86b189b282 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  mat4 getSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index 3b12a07a27..4a0815a163 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -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; diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl new file mode 100644 index 0000000000..b0d029dbf4 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl @@ -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; +	 +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl index 65d9209983..ac3f7189c2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl @@ -5,7 +5,7 @@   * $License$   */ -#version 120 +  vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);  mat4 getObjectSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index 2691fc8ded..44cb78e914 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -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);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl index 164322c3a7..870d593311 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl @@ -5,7 +5,7 @@   * $License$   */ -#version 120 +  uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl index 5ae41cb730..c7a4f86727 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl @@ -5,7 +5,7 @@   * $License$   */ -#version 120 +  mat4 getObjectSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl index a012cb5030..68e4055cf2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);  mat4 getSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl new file mode 100644 index 0000000000..7bc78fe407 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl @@ -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; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index 9748727147..3268618093 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl index 1b7ae06888..78986ab12e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl @@ -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);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl index cf6579a40d..f177fcd8f1 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl @@ -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;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl index 69c93799b5..7eac11287a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  mat4 getSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index d9f021b114..8c75c8045a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -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; diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightMSF.glsl new file mode 100644 index 0000000000..6ca51377c1 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightMSF.glsl @@ -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; +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl index c2d05c601a..862f809de5 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec2 vary_fragcoord;  uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl index 37bfaac32c..75b4dc624a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D diffuseMap;  uniform sampler2D bumpMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl index d884f2e4a5..dc69519a85 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl @@ -5,7 +5,7 @@   * $License$   */ -#version 120 +  varying vec3 vary_mat0;  varying vec3 vary_mat1; diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl index 9b109b2db6..5b6726488b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec3 vary_mat0;  varying vec3 vary_mat1; diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl new file mode 100644 index 0000000000..ef300d5631 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl @@ -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); +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl new file mode 100644 index 0000000000..3eac63076c --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl @@ -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 +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index 35cfb80c93..43af480c50 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -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);  } + diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl new file mode 100644 index 0000000000..e7b5dcce7f --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl @@ -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); +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl index 9a45c03237..2c4caea109 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl @@ -5,7 +5,7 @@   * $License$   */ -#version 120 +  varying vec3 vary_normal; diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl index 03d3322cb6..b56d1493c3 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl @@ -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; diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index 3429877397..d781e08548 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -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; +#extension GL_ARB_texture_rectangle : enable  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); -	  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl index 6c38d220e2..2eed044b7c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl @@ -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); -	  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl index 75b555e8ae..41c149e774 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class1/deferred/giV.glsl b/indra/newview/app_settings/shaders/class1/deferred/giV.glsl index 8dc1410ea5..e86f2896da 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/giV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/giV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec2 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl index e3c15a2ab2..fa811f0d55 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D diffuseMap;  uniform sampler2D normalMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl index 37148b3f1a..723777bd3a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  void main()  { diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl index 78df54d5dc..25e93ae266 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2DRect diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl index 0c820bfc6c..4baf1fc65a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec2 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 609fc4f14f..3c5c780d94 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -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); diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightMSF.glsl new file mode 100644 index 0000000000..6c43679acf --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightMSF.glsl @@ -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; + +	 +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl index 2e3e84dd15..434fb6f534 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec4 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index a9f03f7615..0d25d7792d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  //class 1 -- no shadows diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightMSF.glsl new file mode 100644 index 0000000000..c80a54346e --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightMSF.glsl @@ -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; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index 22ed9dcd40..5efa3200d4 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -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); diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightMSF.glsl new file mode 100644 index 0000000000..feaf38115d --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightMSF.glsl @@ -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; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl index 8e74feb615..c510d8ad77 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl @@ -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;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl index 77f1b2224c..f6b0402bb9 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl @@ -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; diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredMSF.glsl new file mode 100644 index 0000000000..62ae5f917a --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredMSF.glsl @@ -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; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl index ab48d08bbb..bf829bfc56 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFMSF.glsl new file mode 100644 index 0000000000..bf35dfe11c --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFMSF.glsl @@ -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; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl index 12983baa94..876f65ee3a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec2 vary_fragcoord;  uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl index 63b3c9f205..fa3f04bcc8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2DRect depthMap;  uniform sampler2DRect normalMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl index ae57227fe5..eebe930666 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec2 vary_fragcoord;  uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl index 6674c4a5aa..e0c5406483 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl index db3bddc6be..9271a5115c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec4 post_pos; diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl new file mode 100644 index 0000000000..820c82ffd7 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl @@ -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); +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl new file mode 100644 index 0000000000..1ea00f723a --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl @@ -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); +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 29340c7e9f..60082f40d6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -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 diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightMSF.glsl new file mode 100644 index 0000000000..9dfacfb520 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightMSF.glsl @@ -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; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl index 8f0bcca76b..745cc01992 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl index 29fac46bfe..9aaffc15bf 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightMSF.glsl new file mode 100644 index 0000000000..4bb9bad275 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightMSF.glsl @@ -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; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl new file mode 100644 index 0000000000..2cf7d194cc --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl @@ -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);	 +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl new file mode 100644 index 0000000000..c43125dad9 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl @@ -0,0 +1,17 @@ +/**  + * @file starsV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + + + +void main() +{ +	//transform vertex +	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;  +	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; +	gl_FrontColor = gl_Color; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl index 00093836a2..f20886565a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  //class 1, no shadow, no SSAO, should never be called diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightMSF.glsl new file mode 100644 index 0000000000..f20886565a --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightMSF.glsl @@ -0,0 +1,17 @@ +/**  + * @file sunLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + + +//class 1, no shadow, no SSAO, should never be called + +#extension GL_ARB_texture_rectangle : enable + +void main()  +{ +	gl_FragColor = vec4(0,0,0,0); +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl index cd91351ad4..665d8126a0 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -5,7 +5,7 @@   * $License$   */ -#version 120 +  #extension GL_ARB_texture_rectangle : enable @@ -35,7 +35,7 @@ uniform float shadow_offset;  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); diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOMSF.glsl new file mode 100644 index 0000000000..32d1b2149a --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOMSF.glsl @@ -0,0 +1,123 @@ +/**  + * @file sunLightSSAOF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +  + + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +//class 1 -- no shadow, SSAO only + +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +uniform sampler2D noiseMap; + + +// Inputs +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform float ssao_radius; +uniform float ssao_max_radius; +uniform float ssao_factor; +uniform float ssao_factor_inv; + +varying vec2 vary_fragcoord; +varying vec4 vary_light; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +uniform float shadow_bias; +uniform float shadow_offset; + +vec4 getPosition(ivec2 pos_screen, int sample) +{ +	float depth = texelFetch(depthMap, pos_screen, sample).r; +	vec2 sc = pos_screen.xy*2.0; +	sc /= screen_res; +	sc -= vec2(1.0,1.0); +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); +	vec4 pos = inv_proj * ndc; +	pos /= pos.w; +	pos.w = 1.0; +	return pos; +} + +//calculate decreases in ambient lighting when crowded out (SSAO) +float calcAmbientOcclusion(vec4 pos, vec3 norm, int sample) +{ +	float ret = 1.0; +	 +	vec2 kern[8]; +	// exponentially (^2) distant occlusion samples spread around origin +	kern[0] = vec2(-1.0, 0.0) * 0.125*0.125; +	kern[1] = vec2(1.0, 0.0) * 0.250*0.250; +	kern[2] = vec2(0.0, 1.0) * 0.375*0.375; +	kern[3] = vec2(0.0, -1.0) * 0.500*0.500; +	kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625; +	kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750; +	kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875; +	kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000; + +	vec2 pos_screen = vary_fragcoord.xy; +	vec3 pos_world = pos.xyz; +	vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; +		 +	float angle_hidden = 0.0; +	int points = 0; +		 +	float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); +		 +	// it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations unrolling?) +	for (int i = 0; i < 8; i++) +	{ +		ivec2 samppos_screen = ivec2(pos_screen + scale * reflect(kern[i], noise_reflect)); +		vec3 samppos_world = getPosition(samppos_screen, sample).xyz;  +			 +		vec3 diff = pos_world - samppos_world; +		float dist2 = dot(diff, diff); +			 +		// assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area +		// --> solid angle shrinking by the square of distance +		//radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2 +		//(k should vary inversely with # of samples, but this is taken care of later) +			 +		angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); +			 +		// 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"  +		points = points + int(diff.z > -1.0); +	} +		 +	angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); +		 +	ret = (1.0 - (float(points != 0) * angle_hidden)); +	 +	return min(ret, 1.0); +} + +void main()  +{ +	vec2 pos_screen = vary_fragcoord.xy; +	ivec2 itc = ivec2(pos_screen); +		 +	float col = 0; + +	for (int i = 0; i < samples; i++) +	{ +		vec4 pos = getPosition(itc, i); +		vec3 norm = texelFetch(normalMap, itc, i).xyz; +		norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +		col += calcAmbientOcclusion(pos,norm,i); +	} + +	col /= samples; + +	gl_FragColor[0] = 1.0; +	gl_FragColor[1] = col; +	gl_FragColor[2] = 1.0;  +	gl_FragColor[3] = 1.0; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl index 9beb513ad8..814deb3677 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec4 vary_light;  varying vec2 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl index 0edae47918..d005f67bf6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D detail_0;  uniform sampler2D detail_1; diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl index a6163063be..3038fd2966 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec3 vary_normal; diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index c54d9a1e3e..de7e038402 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl index 29689ecbaf..a9bef4292d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec3 vary_normal; diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index e76f598d09..2710422d32 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl index 649e392630..5397290b11 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl index f2023fa5ea..32f5f5f236 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractMSF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractMSF.glsl new file mode 100644 index 0000000000..9267a8585d --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractMSF.glsl @@ -0,0 +1,38 @@ +/**  + * @file glowExtractF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseMap; +uniform float minLuminance; +uniform float maxExtractAlpha; +uniform vec3 lumWeights; +uniform vec3 warmthWeights; +uniform float warmthAmount; + +void main() +{ +	ivec2 itc = ivec2(gl_TexCoord[0].xy); +	vec4 fcol = vec4(0,0,0,0); + +	for (int i = 0; i < samples; i++) +	{ +		vec4 col = texelFetch(diffuseMap, itc, i);	 + +		/// CALCULATING LUMINANCE (Using NTSC lum weights) +		/// http://en.wikipedia.org/wiki/Luma_%28video%29 +		float lum = smoothstep(minLuminance, minLuminance+1.0, dot(col.rgb, lumWeights ) ); +		float warmth = smoothstep(minLuminance, minLuminance+1.0, max(col.r * warmthWeights.r, max(col.g * warmthWeights.g, col.b * warmthWeights.b)) );  +	 +		fcol += vec4(col.rgb, max(col.a, mix(lum, warmth, warmthAmount) * maxExtractAlpha)); +	} + +	gl_FragColor = fcol/samples; +} diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl index 0ca0608b45..76736fed53 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  void main()   { diff --git a/indra/newview/app_settings/shaders/class1/effects/glowF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowF.glsl index 65fc2e9f99..d3225546b3 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D diffuseMap;  uniform float glowStrength; diff --git a/indra/newview/app_settings/shaders/class1/effects/glowV.glsl b/indra/newview/app_settings/shaders/class1/effects/glowV.glsl index 0bd44cec90..9bb41626ae 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowV.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform vec2 glowDelta; diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl index ac00f15b35..cdc2ca3da2 100644 --- a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D detail0;  uniform sampler2D detail1; diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl index 1e19ee7699..8af981915b 100644 --- a/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl index 34f78565a5..d94d986581 100644 --- a/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  // this class1 shader is just a copy of terrainF diff --git a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl index 0dfac84a6e..06854fcc0a 100644 --- a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D diffuseMap;  uniform sampler2D bumpMap;    diff --git a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl index 4e9c09b1ea..0f24e3c35a 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  vec3 scaleSoftClip(vec3 inColor);  vec3 atmosTransport(vec3 inColor); diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl index a34cf23790..630459b324 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  vec4 applyWaterFog(vec4 color)  { diff --git a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl index 161c794c68..831d6a761c 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl index 6f821f893d..f6c6d945de 100644 --- a/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl index d1c98bf70c..f114f766bf 100644 --- a/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  void main()  { diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl index 9c59e8c3ad..1796730c92 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl index 1fee99c446..bfe0be9fdf 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl index fb5da21c72..6f1fe91007 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl index 1bdaccf9b8..19072cd052 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl @@ -6,7 +6,7 @@   */ -#version 120 +  uniform sampler2D diffuseMap;  uniform samplerCube environmentMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl index 2e94d3bbf1..0ae6dc89e2 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl @@ -6,7 +6,7 @@   */ -#version 120 +  uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl index 714f9a2551..5d4bf2c33e 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  float calcDirectionalLight(vec3 n, vec3 l)  { diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl index 65b45f8081..574252af12 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  float calcDirectionalLight(vec3 n, vec3 l) diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl index 7f65ea76f7..29f575b7e5 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl index 8f13e6dc04..65da5a6825 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl index 56f31f6a79..d491f1102e 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  float calcDirectionalLight(vec3 n, vec3 l); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl index 64d549ff52..ef38ee9699 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  float calcDirectionalLight(vec3 n, vec3 l); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl index c5d084c132..286c92326b 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl index 732d246471..772a420e33 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da);  vec3 atmosAmbient(vec3 light); diff --git a/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl index 73e1a1ec26..da60a3ddf5 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  float calcDirectionalLight(vec3 n, vec3 l); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl index afc3dc89bf..c0b72115dd 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  void fullbright_lighting(); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl index 3dc4294f67..391c06edc8 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  void fullbright_shiny_lighting(); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl index f0baeeeee5..f44a5ce32e 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl @@ -5,7 +5,7 @@   * $License$   */ -#version 120 +  void calcAtmospherics(vec3 inPositionEye);  mat4 getObjectSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl index 02367b9439..31e0f0a429 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl index 5daf66fb31..8ffb252f57 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl @@ -5,7 +5,7 @@   * $License$   */ -#version 120 +  void fullbright_shiny_lighting_water(); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl index 02ff3cc2a9..e5dafa8c78 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl @@ -5,7 +5,7 @@   * $License$   */ -#version 120 +  void calcAtmospherics(vec3 inPositionEye);  mat4 getObjectSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl index 38e07dbd80..3382384c99 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl index afaac4f69c..220f26614f 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  void fullbright_lighting_water(); diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl index 2cf7a69baa..d079de5377 100644 --- a/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  void shiny_lighting(); diff --git a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl index 4146646058..cd655f3bb5 100644 --- a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl @@ -5,7 +5,7 @@   * $License$   */ -#version 120 +  vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);  void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl index 6ea83b721d..68a086dbc1 100644 --- a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl index e3babe2210..4649d1c47c 100644 --- a/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  void shiny_lighting_water(); diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl index d449d37c0c..b4e4dcfbbf 100644 --- a/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl @@ -5,8 +5,6 @@   * $/LicenseInfo$   */ -#version 120 -  void default_lighting();  void main()  diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl index be38a14d52..900448035c 100644 --- a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl @@ -5,7 +5,7 @@   * $License$   */ -#version 120 +  vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);  void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl index 0d8e14e2e3..b493f76fcc 100644 --- a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);  void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl index 68bd81e029..4ec5ee43b4 100644 --- a/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  void default_lighting_water(); diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl index f337bde329..3d05850ab3 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  vec3 atmosLighting(vec3 light)  { diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl index 4b402a7028..f1a0af21af 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  vec3 atmosAmbient(vec3 light)  { diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl index 20948b1e46..73bbd57315 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  void setPositionEye(vec3 v); diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl index 8a2c2a7186..e0eb7b3767 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec3 vary_PositionEye; diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl index a1dd4ed5fe..a251213ff5 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec3 vary_PositionEye; diff --git a/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl index 7aed1fd3b5..4958cb2f72 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform vec4 gamma; diff --git a/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl index 6780dc4d3e..75929bc609 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  vec3 atmosTransport(vec3 light)  { diff --git a/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl b/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl index 172c2ca078..3e8b719f93 100644 --- a/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl +++ b/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol);  void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index 6dfc1b952c..681e52de2a 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -5,11 +5,10 @@   * $/LicenseInfo$   */ -#version 120 +  #extension GL_ARB_texture_rectangle : enable -uniform sampler2D diffuseMap;  uniform sampler2DRectShadow shadowMap0;  uniform sampler2DRectShadow shadowMap1;  uniform sampler2DRectShadow shadowMap2; @@ -105,7 +104,7 @@ void main()  		}  	} -	vec4 diff= texture2D(diffuseMap, gl_TexCoord[0].xy); +	vec4 diff = diffuseLookup(gl_TexCoord[0].xy);  	vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, gl_Color.a);  	vec4 color = diff * col; diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl new file mode 100644 index 0000000000..5350359f75 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl @@ -0,0 +1,125 @@ +/**  + * @file alphaF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2DRect depthMap; +uniform sampler2D diffuseMap; + +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform vec2 screen_res; +uniform vec2 shadow_res; + +vec3 atmosLighting(vec3 light); +vec3 scaleSoftClip(vec3 light); + +varying vec3 vary_ambient; +varying vec3 vary_directional; +varying vec3 vary_fragcoord; +varying vec3 vary_position; +varying vec3 vary_pointlight_col; + +uniform float shadow_bias; + +uniform mat4 inv_proj; + +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.xyz /= pos.w; +	pos.w = 1.0; +	return pos; +} + +float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +{ +	stc.xyz /= stc.w; +	stc.z += shadow_bias; +	 +	float cs = shadow2DRect(shadowMap, stc.xyz).x; +	float shadow = cs; + +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, scl, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, -scl, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, scl, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, -scl, 0.0)).x, cs); +			 +	return shadow/5.0; +} + + +void main()  +{ +	vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; +	frag *= screen_res; +	 +	float shadow = 1.0; +	vec4 pos = vec4(vary_position, 1.0); +	 +	vec4 spos = pos; +		 +	if (spos.z > -shadow_clip.w) +	{	 +		vec4 lpos; +		 +		if (spos.z < -shadow_clip.z) +		{ +			lpos = shadow_matrix[3]*spos; +			lpos.xy *= shadow_res; +			shadow = pcfShadow(shadowMap3, lpos, 1.5); +			shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); +		} +		else if (spos.z < -shadow_clip.y) +		{ +			lpos = shadow_matrix[2]*spos; +			lpos.xy *= shadow_res; +			shadow = pcfShadow(shadowMap2, lpos, 1.5); +		} +		else if (spos.z < -shadow_clip.x) +		{ +			lpos = shadow_matrix[1]*spos; +			lpos.xy *= shadow_res; +			shadow = pcfShadow(shadowMap1, lpos, 1.5); +		} +		else +		{ +			lpos = shadow_matrix[0]*spos; +			lpos.xy *= shadow_res; +			shadow = pcfShadow(shadowMap0, lpos, 1.5); +		} +	} +	 +	vec4 diff = texture2D(diffuseMap,gl_TexCoord[0].xy); + +	vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, 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 = gl_Color; +	gl_FragColor = color; +	//gl_FragColor.r = 0.0; +	//gl_FragColor = vec4(1,shadow,1,1); +	 +} + diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl index dfb36980b0..948a52da5b 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl @@ -5,7 +5,7 @@   * $License$   */ -#version 120 +  vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);  void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl index f6160815eb..f616ecc872 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);  void calcAtmospherics(vec3 inPositionEye); @@ -22,6 +22,7 @@ varying vec3 vary_directional;  varying vec3 vary_fragcoord;  varying vec3 vary_position;  varying vec3 vary_pointlight_col; +varying float vary_texture_index;  uniform float near_clip;  uniform float shadow_offset; @@ -60,11 +61,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)); @@ -99,7 +102,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);  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl index 0ae09df0c6..01e40afc4f 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);  mat4 getSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl b/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl index 3155f3f929..729e4b5543 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  #extension GL_ARB_texture_rectangle : enable @@ -22,7 +22,7 @@ uniform vec2 screen_res;  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; diff --git a/indra/newview/app_settings/shaders/class2/deferred/edgeMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/edgeMSF.glsl new file mode 100644 index 0000000000..b22bc5b288 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/edgeMSF.glsl @@ -0,0 +1,74 @@ +/**  + * @file edgeF.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; + +varying vec2 vary_fragcoord; + +uniform float depth_cutoff; +uniform float norm_cutoff; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +float getDepth(ivec2 pos_screen, int sample) +{ +	float z = texelFetch(depthMap, pos_screen, sample).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; +} + +void main()  +{ +	float e = 0; +	 +	ivec2 itc = ivec2(vary_fragcoord.xy); + +	for (int i = 0; i < samples; i++) +	{	 +		vec3 norm = texelFetch(normalMap, itc, i).xyz; +		norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +		float depth = getDepth(itc, i); +	 +		vec2 tc = vary_fragcoord.xy; +	 +		int sc = 1; +	 +		vec2 de; +		de.x = (depth-getDepth(itc+ivec2(sc, sc),i)) + (depth-getDepth(itc+ivec2(-sc, -sc), i)); +		de.y = (depth-getDepth(itc+ivec2(-sc, sc),i)) + (depth-getDepth(itc+ivec2(sc, -sc), i)); +		de /= depth; +		de *= de; +		de = step(depth_cutoff, de); +	 +		vec2 ne; +		vec3 nexnorm = texelFetch(normalMap, itc+ivec2(-sc,-sc), i).rgb; +		nexnorm = vec3((nexnorm.xy-0.5)*2.0,nexnorm.z); // unpack norm +		ne.x = dot(nexnorm, norm); +		vec3 neynorm = texelFetch(normalMap, itc+ivec2(sc,sc), i).rgb; +		neynorm = vec3((neynorm.xy-0.5)*2.0,neynorm.z); // unpack norm +		ne.y = dot(neynorm, norm); +	 +		ne = 1.0-ne; +	 +		ne = step(norm_cutoff, ne); + +		e += dot(de,de)+dot(ne,ne); +	} + +	e /= samples; +	 +	gl_FragColor.a = e; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/edgeV.glsl b/indra/newview/app_settings/shaders/class2/deferred/edgeV.glsl index b3413c301f..393084a3db 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/edgeV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/edgeV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec2 vary_fragcoord;  uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index d6cd984ebe..f54186ffca 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  #extension GL_ARB_texture_rectangle : enable @@ -91,7 +91,7 @@ vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)  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); diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightMSF.glsl new file mode 100644 index 0000000000..fee32be3e3 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightMSF.glsl @@ -0,0 +1,244 @@ +/**  + * @file multiSpotLightF.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 depthMap; +uniform sampler2DMS normalMap; +uniform sampler2DRect lightMap; +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()  +{ +	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); + +	float shadow = 1.0; + +	if (proj_shadow_idx >= 0) +	{ +		vec4 shd = texture2DRect(lightMap, frag); +		float sh[2]; +		sh[0] = shd.b; +		sh[1] = shd.a; +		shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.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; +			norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +	 +			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*shadow; +							amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; +						} +		 +						//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); +						vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); +							 +						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*shadow; +								} +							} +						} +					} + +					fcol += col; +					wght++; +				} +			} +		} +	} +	 +	if (wght <= 0) +	{ +		discard; +	} + +	gl_FragColor.rgb = fcol/samples;	 +	gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 0160e84278..66a1a8515f 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  #extension GL_ARB_texture_rectangle : enable @@ -71,7 +71,7 @@ vec4 getPosition_d(vec2 pos_screen, float depth)  vec4 getPosition(vec2 pos_screen)  { //get position in screen space (world units) given window coordinate and depth map -	float depth = texture2DRect(depthMap, pos_screen.xy).a; +	float depth = texture2DRect(depthMap, pos_screen.xy).r;  	return getPosition_d(pos_screen, depth);  } @@ -258,7 +258,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 @@ -288,54 +288,8 @@ void main()  		float sa = dot(refnormpersp, vary_light.xyz);  		vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a; -		/* -		// screen-space cheap fakey reflection map -		// -		vec3 refnorm = normalize(reflect(vec3(0,0,-1), norm.xyz)); -		depth -= 0.5; // unbias depth -		// first figure out where we'll make our 2D guess from -		vec2 ref2d = (0.25 * screen_res.y) * (refnorm.xy) * abs(refnorm.z) / depth; -		// Offset the guess source a little according to a trivial -		// checkerboard dither function and spec.a. -		// This is meant to be similar to sampling a blurred version -		// of the diffuse map.  LOD would be better in that regard. -		// The goal of the blur is to soften reflections in surfaces -		// with low shinyness, and also to disguise our lameness. -		float checkerboard = floor(mod(tc.x+tc.y, 2.0)); // 0.0, 1.0 -		float checkoffset = (3.0 + (7.0*(1.0-spec.a)))*(checkerboard-0.5); -		ref2d += vec2(checkoffset, checkoffset); -		ref2d += tc.xy; // use as offset from destination -		// Get attributes from the 2D guess point. -		// We average two samples of diffuse (not of anything else) per -		// pixel to try to reduce aliasing some more. -		vec3 refcol = 0.5 * (texture2DRect(diffuseRect, ref2d + vec2(0.0, -checkoffset)).rgb + -				     texture2DRect(diffuseRect, ref2d + vec2(-checkoffset, 0.0)).rgb); -		float refdepth = texture2DRect(depthMap, ref2d).a; -		vec3 refpos = getPosition_d(ref2d, refdepth).xyz; -		float refshad = texture2DRect(lightMap, ref2d).r; -		vec3 refn = texture2DRect(normalMap, ref2d).rgb; -		refn = vec3((refn.xy-0.5)*2.0,refn.z); // unpack norm -		refn = normalize(refn); -		// figure out how appropriate our guess actually was -		float refapprop = max(0.0, dot(-refnorm, normalize(pos - refpos))); -		// darken reflections from points which face away from the reflected ray - our guess was a back-face -		//refapprop *= step(dot(refnorm, refn), 0.0); -		refapprop = min(refapprop, max(0.0, -dot(refnorm, refn))); // more conservative variant -		// get appropriate light strength for guess-point -		// reflect light direction to increase the illusion that -		// these are reflections. -		vec3 reflight = reflect(lightnorm.xyz, norm.xyz); -		float reflit = min(max(dot(refn, reflight.xyz), 0.0), refshad); -		// apply sun color to guess-point, dampen according to inappropriateness of guess -		float refmod = min(refapprop, reflit); -		vec3 refprod = vary_SunlitColor * refcol.rgb * refmod; -		vec3 ssshiny = (refprod * spec.a); -		ssshiny *= 0.3; // dampen it even more -		*/ -		vec3 ssshiny = vec3(0,0,0); -  		// add the two types of shiny together -		col += (ssshiny + dumbshiny) * spec.rgb; +		col += dumbshiny * spec.rgb;  	}  	col = atmosLighting(col); diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl new file mode 100644 index 0000000000..0bae10ca7d --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl @@ -0,0 +1,307 @@ +/**  + * @file softenLightMSF.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 sampler2DRect lightMap; +uniform sampler2DMS depthMap; +uniform sampler2D	  noiseMap; +uniform samplerCube environmentMap; +uniform sampler2D	  lightFunc; +uniform vec3 gi_quad; + +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 vec4 shadow_clip; +uniform mat3 ssao_effect_mat; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +varying vec4 vary_light; +varying vec2 vary_fragcoord; + +vec3 vary_PositionEye; + +vec3 vary_SunlitColor; +vec3 vary_AmblitColor; +vec3 vary_AdditiveColor; +vec3 vary_AtmosAttenuation; + +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; +} + +void main()  +{ +	vec2 tc = vary_fragcoord.xy; +	ivec2 itc = ivec2(tc); + +	vec3 fcol = vec3(0,0,0); + +	vec2 scol_ambocc = texture2DRect(lightMap, tc).rg; +	float ambocc = scol_ambocc.g; + +	for (int i = 0; i < samples; ++i) +	{ +		float depth = texelFetch(depthMap, itc.xy, 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 +			 +		float da = max(dot(norm.xyz, vary_light.xyz), 0.0); +	 +		vec4 diffuse = texelFetch(diffuseRect, itc, i); +		vec4 spec = texelFetch(specularRect, itc, i); +	 +		float amb = 0; + +		float scol = max(scol_ambocc.r, diffuse.a);  +		amb += ambocc; + +		calcAtmospherics(pos.xyz, ambocc); +	 +		vec3 col = atmosAmbient(vec3(0)); +		col += atmosAffectDirectionalLight(max(min(da, scol), 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*scol_ambocc.r*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/samples;  +	gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl index 8f0bcca76b..745cc01992 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index 50b9ef276e..cd3828fbd4 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl new file mode 100644 index 0000000000..ec9b547a47 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl @@ -0,0 +1,245 @@ +/**  + * @file multiSpotLightF.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 depthMap; +uniform sampler2DMS normalMap; +uniform sampler2DRect lightMap; +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; + +	float shadow = 1.0; +	 +	if (proj_shadow_idx >= 0) +	{ +		vec4 shd = texture2DRect(lightMap, frag.xy); +		float sh[2]; +		sh[0] = shd.b; +		sh[1] = shd.a; +		shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.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; +			norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +	 +			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*shadow; +							amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; +						} +		 +						//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); +						vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); +							 +						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*shadow; +								} +							} +						} +					} + +					fcol += col; +					wght++; +				} +			} +		} +	} +	 +	if (wght <= 0) +	{ +		discard; +	} + +	gl_FragColor.rgb = fcol/wght;	 +	gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index 4369b3b34f..315139b415 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  #extension GL_ARB_texture_rectangle : enable @@ -45,7 +45,7 @@ uniform float spot_shadow_offset;  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); diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightMSF.glsl new file mode 100644 index 0000000000..63d13c996d --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightMSF.glsl @@ -0,0 +1,202 @@ +/**  + * @file sunLightMSF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +//class 2, shadows, no SSAO + +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2DShadow shadowMap4; +uniform sampler2DShadow shadowMap5; + + +// Inputs +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform float ssao_radius; +uniform float ssao_max_radius; +uniform float ssao_factor; +uniform float ssao_factor_inv; + +varying vec2 vary_fragcoord; +varying vec4 vary_light; + +uniform mat4 inv_proj; +uniform vec2 screen_res; +uniform vec2 shadow_res; +uniform vec2 proj_shadow_res; + +uniform float shadow_bias; +uniform float shadow_offset; + +uniform float spot_shadow_bias; +uniform float spot_shadow_offset; + +vec4 getPosition(ivec2 pos_screen, int sample) +{ +	float depth = texelFetch(depthMap, pos_screen.xy, 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; +} + +float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +{ +	stc.xyz /= stc.w; +	stc.z += shadow_bias*scl; +	 +	float cs = shadow2DRect(shadowMap, stc.xyz).x; +	float shadow = cs; + +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, 1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, -1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, 1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, -1.5, 0.0)).x, cs); +			 +	return shadow/5.0; +	 +	//return shadow; +} + +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl) +{ +	stc.xyz /= stc.w; +	stc.z += spot_shadow_bias*scl; +	 +	float cs = shadow2D(shadowMap, stc.xyz).x; +	float shadow = cs; + +	vec2 off = 1.5/proj_shadow_res; +	 +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs); +				 +	return shadow/5.0; +	 +	//return shadow; +} + +void main()  +{ +	vec2 pos_screen = vary_fragcoord.xy; +	ivec2 itc = ivec2(pos_screen); + +	//try doing an unproject here +	 +	vec4 fcol = vec4(0,0,0,0); + +	for (int i = 0; i < samples; i++) +	{ +		vec4 pos = getPosition(itc, i); +	 +		vec4 nmap4 = texelFetch(normalMap, itc, i); +		nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm +		float displace = nmap4.w; +		vec3 norm = nmap4.xyz; +	 +		/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL +		{ +			gl_FragColor = vec4(0.0); // doesn't matter +			return; +		}*/ +	 +		float shadow = 1.0; +		float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); + +		vec3 shadow_pos = pos.xyz + displace*norm; +		vec3 offset = vary_light.xyz * (1.0-dp_directional_light); +	 +		vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0); +	 +		if (spos.z > -shadow_clip.w) +		{	 +			if (dp_directional_light == 0.0) +			{ +				// if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup +				shadow = 0.0; +			} +			else +			{ +				vec4 lpos; +			 +				if (spos.z < -shadow_clip.z) +				{ +					lpos = shadow_matrix[3]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap3, lpos, 0.25); +					shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); +				} +				else if (spos.z < -shadow_clip.y) +				{ +					lpos = shadow_matrix[2]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap2, lpos, 0.5); +				} +				else if (spos.z < -shadow_clip.x) +				{ +					lpos = shadow_matrix[1]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap1, lpos, 0.75); +				} +				else +				{ +					lpos = shadow_matrix[0]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap0, lpos, 1.0); +				} +		 +				// take the most-shadowed value out of these two: +				//  * the blurred sun shadow in the light (shadow) map +				//  * an unblurred dot product between the sun and this norm +				// the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting +				shadow = min(shadow, dp_directional_light); +			 +				//lpos.xy /= lpos.w*32.0; +				//if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1) +				//{ +				//	shadow = 0.0; +				//} +			 +			} +		} +		else +		{ +			// more distant than the shadow map covers +			shadow = 1.0; +		} +	 +		fcol[0] += shadow; +		fcol[1] += 1.0; + +		spos = vec4(shadow_pos+norm*spot_shadow_offset, 1.0); +	 +		//spotlight shadow 1 +		vec4 lpos = shadow_matrix[4]*spos; +		fcol[2] += pcfShadow(shadowMap4, lpos, 0.8);  +	 +		//spotlight shadow 2 +		lpos = shadow_matrix[5]*spos; +		fcol[3] += pcfShadow(shadowMap5, lpos, 0.8);  +	} + +	gl_FragColor = fcol/samples; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 847b36b1ac..d53850b489 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -5,7 +5,7 @@   * $License$   */ -#version 120 +  #extension GL_ARB_texture_rectangle : enable @@ -45,7 +45,7 @@ uniform float spot_shadow_offset;  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); @@ -234,7 +234,7 @@ void main()  	gl_FragColor[0] = shadow;  	gl_FragColor[1] = calcAmbientOcclusion(pos, norm); -	spos.xyz = shadow_pos+offset*spot_shadow_offset; +	spos.xyz = shadow_pos+norm*spot_shadow_offset;  	//spotlight shadow 1  	vec4 lpos = shadow_matrix[4]*spos; diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOMSF.glsl new file mode 100644 index 0000000000..a2a76eed9f --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOMSF.glsl @@ -0,0 +1,241 @@ +/**  + * @file sunLightSSAOF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +  + + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +//class 2 -- shadows and SSAO + +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2DShadow shadowMap4; +uniform sampler2DShadow shadowMap5; +uniform sampler2D noiseMap; + +// Inputs +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform float ssao_radius; +uniform float ssao_max_radius; +uniform float ssao_factor; +uniform float ssao_factor_inv; + +varying vec2 vary_fragcoord; +varying vec4 vary_light; + +uniform mat4 inv_proj; +uniform vec2 screen_res; +uniform vec2 shadow_res; +uniform vec2 proj_shadow_res; + +uniform float shadow_bias; +uniform float shadow_offset; + +uniform float spot_shadow_bias; +uniform float spot_shadow_offset; + +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; +} + +//calculate decreases in ambient lighting when crowded out (SSAO) +float calcAmbientOcclusion(vec4 pos, vec3 norm, int sample) +{ +	float ret = 1.0; + +	vec2 kern[8]; +	// exponentially (^2) distant occlusion samples spread around origin +	kern[0] = vec2(-1.0, 0.0) * 0.125*0.125; +	kern[1] = vec2(1.0, 0.0) * 0.250*0.250; +	kern[2] = vec2(0.0, 1.0) * 0.375*0.375; +	kern[3] = vec2(0.0, -1.0) * 0.500*0.500; +	kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625; +	kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750; +	kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875; +	kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000; + +	vec2 pos_screen = vary_fragcoord.xy; +	vec3 pos_world = pos.xyz; +	vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; +		 +	float angle_hidden = 0.0; +	int points = 0; +		 +	float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); +		 +	// it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?) +	for (int i = 0; i < 8; i++) +	{ +		ivec2 samppos_screen = ivec2(pos_screen + scale * reflect(kern[i], noise_reflect)); +		vec3 samppos_world = getPosition(samppos_screen, sample).xyz;  +			 +		vec3 diff = pos_world - samppos_world; +		float dist2 = dot(diff, diff); +			 +		// assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area +		// --> solid angle shrinking by the square of distance +		//radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2 +		//(k should vary inversely with # of samples, but this is taken care of later) +			 +		angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); +			 +		// 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"  +		points = points + int(diff.z > -1.0); +	} +		 +	angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); +		 +	ret = (1.0 - (float(points != 0) * angle_hidden)); +	 +	return min(ret, 1.0); +} + +float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +{ +	stc.xyz /= stc.w; +	stc.z += shadow_bias*scl; +	 +	float cs = shadow2DRect(shadowMap, stc.xyz).x; +	float shadow = cs; + +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, 1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, -1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, 1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, -1.5, 0.0)).x, cs); +			 +	return shadow/5.0; +	 +	//return shadow; +} + +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl) +{ +	stc.xyz /= stc.w; +	stc.z += spot_shadow_bias*scl; +	 +	float cs = shadow2D(shadowMap, stc.xyz).x; +	float shadow = cs; + +	vec2 off = 1.5/proj_shadow_res; +	 +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs); +	 +			 +	return shadow/5.0; +	 +	//return shadow; +} + +void main()  +{ +	vec2 pos_screen = vary_fragcoord.xy; +	ivec2 itc = ivec2(pos_screen); +	vec4 fcol = vec4(0,0,0,0); + +	for (int i = 0; i < samples; i++) +	{ +		vec4 pos = getPosition(itc, i); +	 +		vec4 nmap4 = texelFetch(normalMap, itc, i); +		nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm +		float displace = nmap4.w; +		vec3 norm = nmap4.xyz; +	 +		float shadow = 1.0; +		float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); + +		vec3 shadow_pos = pos.xyz + displace*norm; +		vec3 offset = vary_light.xyz * (1.0-dp_directional_light); +	 +		vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0); +	 +		if (spos.z > -shadow_clip.w) +		{	 +			if (dp_directional_light == 0.0) +			{ +				// if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup +				shadow = 0.0; +			} +			else +			{ +				vec4 lpos; +			 +				if (spos.z < -shadow_clip.z) +				{ +					lpos = shadow_matrix[3]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap3, lpos, 0.25); +					shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); +				} +				else if (spos.z < -shadow_clip.y) +				{ +					lpos = shadow_matrix[2]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap2, lpos, 0.5); +				} +				else if (spos.z < -shadow_clip.x) +				{ +					lpos = shadow_matrix[1]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap1, lpos, 0.75); +				} +				else +				{ +					lpos = shadow_matrix[0]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap0, lpos, 1.0); +				} +		 +				// take the most-shadowed value out of these two: +				//  * the blurred sun shadow in the light (shadow) map +				//  * an unblurred dot product between the sun and this norm +				// the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting +				shadow = min(shadow, dp_directional_light); +			 +			} +		} +		else +		{ +			// more distant than the shadow map covers +			shadow = 1.0; +		} +	 +		 +		fcol[0] += shadow; +		fcol[1] += calcAmbientOcclusion(pos, norm, i); + +		spos.xyz = shadow_pos+offset*spot_shadow_offset; +	 +		//spotlight shadow 1 +		vec4 lpos = shadow_matrix[4]*spos; +		fcol[2] += pcfShadow(shadowMap4, lpos, 0.8);  +	 +		//spotlight shadow 2 +		lpos = shadow_matrix[5]*spos; +		fcol[3] += pcfShadow(shadowMap5, lpos, 0.8);  +	} +		 +	gl_FragColor = fcol / samples; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl index 9beb513ad8..814deb3677 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec4 vary_light;  varying vec2 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class2/effects/blurF.glsl b/indra/newview/app_settings/shaders/class2/effects/blurF.glsl index a4ad0bfa15..dff4d4a68f 100644 --- a/indra/newview/app_settings/shaders/class2/effects/blurF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/blurF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2DRect RenderTexture;  uniform float bloomStrength; diff --git a/indra/newview/app_settings/shaders/class2/effects/blurV.glsl b/indra/newview/app_settings/shaders/class2/effects/blurV.glsl index d471a6c5e5..de469542f9 100644 --- a/indra/newview/app_settings/shaders/class2/effects/blurV.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/blurV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform vec2 texelSize;  uniform vec2 blurDirection; diff --git a/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl b/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl index 66880b958e..8871bb3fc7 100644 --- a/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2DRect RenderTexture;  uniform float brightness; diff --git a/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl b/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl index c35c500d62..9c52b8dd5d 100644 --- a/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  void main(void)  { diff --git a/indra/newview/app_settings/shaders/class2/effects/extractF.glsl b/indra/newview/app_settings/shaders/class2/effects/extractF.glsl index e77baa5bee..713f8021de 100644 --- a/indra/newview/app_settings/shaders/class2/effects/extractF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/extractF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2DRect RenderTexture;  uniform float extractLow; diff --git a/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl b/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl index 8e0eec6f5e..fd94b2e95f 100644 --- a/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2DRect RenderTexture;  uniform sampler2D NoiseTexture; diff --git a/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl b/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl index 98a50e22fc..a1a9c9716c 100644 --- a/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2DRect RenderTexture; diff --git a/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl b/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl index bbb8951f3a..9527dc469b 100644 --- a/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D detail_0;  uniform sampler2D detail_1; diff --git a/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl b/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl index 84906c16bf..2658bee88d 100644 --- a/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl b/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl index 7590c542ef..974e227b77 100644 --- a/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D detail_0;  uniform sampler2D detail_1; diff --git a/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl index 900f1a6cb8..702e0881ac 100644 --- a/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D diffuseMap;  uniform sampler2D bumpMap;    diff --git a/indra/newview/app_settings/shaders/class2/environment/waterF.glsl b/indra/newview/app_settings/shaders/class2/environment/waterF.glsl index f4f6b6e90f..c4e4bc08c5 100644 --- a/indra/newview/app_settings/shaders/class2/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/waterF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  vec3 scaleSoftClip(vec3 inColor);  vec3 atmosTransport(vec3 inColor); diff --git a/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl index 9f3328cbf0..b66b72b401 100644 --- a/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform vec4 lightnorm;  uniform vec4 waterPlane; diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl index 342bc2ab66..4c31602736 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl @@ -5,16 +5,14 @@   * $/LicenseInfo$   */ -#version 120 -uniform sampler2D diffuseMap;  vec3 atmosLighting(vec3 light);  vec3 scaleSoftClip(vec3 light);  void default_lighting()   { -	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color; +	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;  	color.rgb = atmosLighting(color.rgb); diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl index dad18b5883..95bd052b5d 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl @@ -5,16 +5,14 @@   * $/LicenseInfo$   */ -#version 120 -uniform sampler2D diffuseMap;  vec3 fullbrightAtmosTransport(vec3 light);  vec3 fullbrightScaleSoftClip(vec3 light);  void fullbright_lighting()  { -	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color; +	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;  	color.rgb = fullbrightAtmosTransport(color.rgb); diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightNonIndexedF.glsl new file mode 100644 index 0000000000..b1e61e1a33 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightNonIndexedF.glsl @@ -0,0 +1,25 @@ +/**  + * @file lightFullbrightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + + +vec3 fullbrightAtmosTransport(vec3 light); +vec3 fullbrightScaleSoftClip(vec3 light); + +uniform sampler2D diffuseMap; + +void fullbright_lighting() +{ +	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color; +	 +	color.rgb = fullbrightAtmosTransport(color.rgb); +	 +	color.rgb = fullbrightScaleSoftClip(color.rgb); + +	gl_FragColor = color; +} + diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl index 73ff81e03a..26f0ea84e0 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl @@ -5,9 +5,8 @@   * $/LicenseInfo$   */ -#version 120 -uniform sampler2D diffuseMap; +  uniform samplerCube environmentMap;  vec3 fullbrightShinyAtmosTransport(vec3 light); @@ -15,7 +14,7 @@ vec3 fullbrightScaleSoftClip(vec3 light);  void fullbright_shiny_lighting()  { -	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy); +	vec4 color = diffuseLookup(gl_TexCoord[0].xy);  	color.rgb *= gl_Color.rgb;  	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	 diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyNonIndexedF.glsl new file mode 100644 index 0000000000..953298da0d --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyNonIndexedF.glsl @@ -0,0 +1,32 @@ +/**  + * @file lightFullbrightShinyF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + + +uniform samplerCube environmentMap; +uniform sampler2D diffuseMap; + +vec3 fullbrightShinyAtmosTransport(vec3 light); +vec3 fullbrightScaleSoftClip(vec3 light); + +void fullbright_shiny_lighting() +{ +	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy); +	color.rgb *= gl_Color.rgb; +	 +	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	 +	color.rgb = mix(color.rgb, envColor.rgb, gl_Color.a); + +	color.rgb = fullbrightShinyAtmosTransport(color.rgb); + +	color.rgb = fullbrightScaleSoftClip(color.rgb); + +	color.a = max(color.a, gl_Color.a); + +	gl_FragColor = color; +} + diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl index 9b4b584369..a6e10a249d 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl @@ -5,9 +5,9 @@   * $License$   */ -#version 120 -uniform sampler2D diffuseMap; + +  uniform samplerCube environmentMap;  vec3 fullbrightShinyAtmosTransport(vec3 light); @@ -16,7 +16,7 @@ vec4 applyWaterFog(vec4 color);  void fullbright_shiny_lighting_water()  { -	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy); +	vec4 color = diffuseLookup(gl_TexCoord[0].xy);  	color.rgb *= gl_Color.rgb;  	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	 diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterNonIndexedF.glsl new file mode 100644 index 0000000000..b4bb665a2b --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterNonIndexedF.glsl @@ -0,0 +1,32 @@ +/**  + * @file lightFullbrightShinyWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +  + + + +uniform samplerCube environmentMap; +uniform sampler2D diffuseMap; + +vec3 fullbrightShinyAtmosTransport(vec3 light); +vec3 fullbrightScaleSoftClip(vec3 light); +vec4 applyWaterFog(vec4 color); + +void fullbright_shiny_lighting_water() +{ +	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy); +	color.rgb *= gl_Color.rgb; +	 +	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	 +	color.rgb = mix(color.rgb, envColor.rgb, gl_Color.a); + +	color.rgb = fullbrightShinyAtmosTransport(color.rgb); +	color.rgb = fullbrightScaleSoftClip(color.rgb); +	color.a = max(color.a, gl_Color.a); + +	gl_FragColor = applyWaterFog(color); +} + diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl index 3d46c8d874..887d4130e7 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl @@ -5,16 +5,16 @@   * $/LicenseInfo$   */ -#version 120 -uniform sampler2D diffuseMap; + +vec4 diffuseLookup(vec2 texcoord);  vec3 fullbrightAtmosTransport(vec3 light);  vec4 applyWaterFog(vec4 color);  void fullbright_lighting_water()  { -	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color; +	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;  	color.rgb = fullbrightAtmosTransport(color.rgb); diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterNonIndexedF.glsl new file mode 100644 index 0000000000..1234682ae9 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterNonIndexedF.glsl @@ -0,0 +1,23 @@ +/**  + * @file lightFullbrightWaterF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + + +uniform sampler2D diffuseMap; + +vec3 fullbrightAtmosTransport(vec3 light); +vec4 applyWaterFog(vec4 color); + +void fullbright_lighting_water() +{ +	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color; + +	color.rgb = fullbrightAtmosTransport(color.rgb); +	 +	gl_FragColor = applyWaterFog(color); +} + diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightNonIndexedF.glsl new file mode 100644 index 0000000000..149cf791f5 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightNonIndexedF.glsl @@ -0,0 +1,25 @@ +/**  + * @file lightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + + +uniform sampler2D diffuseMap; + +vec3 atmosLighting(vec3 light); +vec3 scaleSoftClip(vec3 light); + +void default_lighting()  +{ +	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color; +	 +	color.rgb = atmosLighting(color.rgb); + +	color.rgb = scaleSoftClip(color.rgb); + +	gl_FragColor = color; +} + diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl index ebe21320b4..300fcac092 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl @@ -5,9 +5,9 @@   * $/LicenseInfo$   */ -#version 120 -uniform sampler2D diffuseMap; + +  uniform samplerCube environmentMap;  vec3 scaleSoftClip(vec3 light); @@ -16,7 +16,7 @@ vec4 applyWaterFog(vec4 color);  void shiny_lighting()  { -	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy); +	vec4 color = diffuseLookup(gl_TexCoord[0].xy);  	color.rgb *= gl_Color.rgb;  	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	 diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightShinyNonIndexedF.glsl new file mode 100644 index 0000000000..e877c0abb1 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightShinyNonIndexedF.glsl @@ -0,0 +1,32 @@ +/**  + * @file lightShinyF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + + + +uniform samplerCube environmentMap; +uniform sampler2D diffuseMap; + +vec3 scaleSoftClip(vec3 light); +vec3 atmosLighting(vec3 light); +vec4 applyWaterFog(vec4 color); + +void shiny_lighting() +{ +	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy); +	color.rgb *= gl_Color.rgb; +	 +	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	 +	color.rgb = mix(color.rgb, envColor.rgb, gl_Color.a); + +	color.rgb = atmosLighting(color.rgb); + +	color.rgb = scaleSoftClip(color.rgb); +	color.a = max(color.a, gl_Color.a); +	gl_FragColor = color; +} + diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl index 7f48e2cf1d..07572fa915 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl @@ -5,10 +5,9 @@   * $/LicenseInfo$   */ -#version 120 -uniform sampler2D diffuseMap; +  uniform samplerCube environmentMap;  vec3 atmosLighting(vec3 light); @@ -16,7 +15,7 @@ vec4 applyWaterFog(vec4 color);  void shiny_lighting_water()  { -	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy); +	vec4 color = diffuseLookup(gl_TexCoord[0].xy);  	color.rgb *= gl_Color.rgb;  	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	 diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterNonIndexedF.glsl new file mode 100644 index 0000000000..3904179427 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterNonIndexedF.glsl @@ -0,0 +1,29 @@ +/**  + * @file lightShinyWaterF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + + + +uniform sampler2D diffuseMap; +uniform samplerCube environmentMap; + +vec3 atmosLighting(vec3 light); +vec4 applyWaterFog(vec4 color); + +void shiny_lighting_water() +{ +	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy); +	color.rgb *= gl_Color.rgb; +	 +	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	 +	color.rgb = mix(color.rgb, envColor.rgb, gl_Color.a); + +	color.rgb = atmosLighting(color.rgb); +	color.a = max(color.a, gl_Color.a); +	gl_FragColor = applyWaterFog(color); +} + diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl index ad1dc4da77..3384f64d07 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  // All lights, no specular highlights diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl index a0f6e019ef..10c770fcc2 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  // All lights, no specular highlights diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl index 97eba92d7b..61341a9f1f 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl @@ -5,16 +5,14 @@   * $/LicenseInfo$   */ -#version 120 -uniform sampler2D diffuseMap;  vec3 atmosLighting(vec3 light);  vec4 applyWaterFog(vec4 color);  void default_lighting_water()  { -	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color; +	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;  	color.rgb = atmosLighting(color.rgb); diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightWaterNonIndexedF.glsl new file mode 100644 index 0000000000..ba850b61d0 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightWaterNonIndexedF.glsl @@ -0,0 +1,23 @@ +/**  + * @file lightWaterF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + + +uniform sampler2D diffuseMap; + +vec3 atmosLighting(vec3 light); +vec4 applyWaterFog(vec4 color); + +void default_lighting_water() +{ +	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color; + +	color.rgb = atmosLighting(color.rgb); + +	gl_FragColor = applyWaterFog(color); +} + diff --git a/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl index fde32ed035..8df2e6f222 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da);  vec3 calcPointLightSpecular(inout vec4 specular, vec3 view, vec3 v, vec3 n, vec3 l, float r, float pw, vec3 lightCol); diff --git a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl index 8fe49e3be0..3d43a1813a 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  float calcDirectionalLight(vec3 n, vec3 l);  float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight); diff --git a/indra/newview/app_settings/shaders/class2/objects/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class2/objects/fullbrightShinyV.glsl new file mode 100644 index 0000000000..f49e74406f --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/objects/fullbrightShinyV.glsl @@ -0,0 +1,35 @@ +/** + * @file fullbrightShinyV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + + +void calcAtmospherics(vec3 inPositionEye); + +uniform vec4 origin; + +varying float vary_texture_index; + +void main() +{ +	//transform vertex +	vec4 vert = vec4(gl_Vertex.xyz,1.0); +	vary_texture_index = gl_Vertex.w; +	gl_Position = gl_ModelViewProjectionMatrix*vert; +	 +	vec4 pos = (gl_ModelViewMatrix * vert); +	vec3 norm = normalize(gl_NormalMatrix * gl_Normal); +	vec3 ref = reflect(pos.xyz, -norm); + +	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; +	gl_TexCoord[1] = gl_TextureMatrix[1]*vec4(ref,1.0); + +	calcAtmospherics(pos.xyz); + +	gl_FrontColor = gl_Color; + +	gl_FogFragCoord = pos.z; +} diff --git a/indra/newview/app_settings/shaders/class2/objects/fullbrightV.glsl b/indra/newview/app_settings/shaders/class2/objects/fullbrightV.glsl new file mode 100644 index 0000000000..3076fa3260 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/objects/fullbrightV.glsl @@ -0,0 +1,29 @@ +/** + * @file fullbrightV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + + +void calcAtmospherics(vec3 inPositionEye); + +varying float vary_texture_index; + +void main() +{ +	//transform vertex +	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 * vert); + +	calcAtmospherics(pos.xyz); + +	gl_FrontColor = gl_Color; + +	gl_FogFragCoord = pos.z; +} diff --git a/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl b/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl index 4cebb06df0..49992d3535 100644 --- a/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl +++ b/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl @@ -5,20 +5,24 @@   * $/LicenseInfo$   */ -#version 120 +  vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);  void calcAtmospherics(vec3 inPositionEye); +varying float vary_texture_index; +  uniform vec4 origin;  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; -	vec4 pos = (gl_ModelViewMatrix * gl_Vertex); +	vec4 pos = (gl_ModelViewMatrix * vert);  	vec3 norm = normalize(gl_NormalMatrix * gl_Normal);  	vec3 ref = reflect(pos.xyz, -norm); diff --git a/indra/newview/app_settings/shaders/class2/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class2/objects/simpleV.glsl new file mode 100644 index 0000000000..5e02391767 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/objects/simpleV.glsl @@ -0,0 +1,33 @@ +/**  + * @file simpleV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + + +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); +void calcAtmospherics(vec3 inPositionEye); + +varying float vary_texture_index; + +void main() +{ +	//transform vertex +	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 * vert); +	 +	vec3 norm = normalize(gl_NormalMatrix * gl_Normal); + +	calcAtmospherics(pos.xyz); + +	vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); +	gl_FrontColor = color; + +	gl_FogFragCoord = pos.z; +} diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl index 77d15fba9a..21a0812c1b 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  //////////////////////////////////////////////////////////  // The fragment shader for the terrain atmospherics diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl index 8c5b864cbe..ab4cf4806d 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  // Output variables  vec3 getSunlitColor(); diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl index 8d365c15ca..b61b0bb396 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  // varying param funcs  void setSunlitColor(vec3 v); diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl index cf9ef30632..3a6585bb33 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec3 vary_PositionEye; diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl index 398f1556a0..0f6e231ca6 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec3 vary_PositionEye; diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl index 13207997b2..20f907a006 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  /////////////////////////////////////////////////////////////////////////  // The fragment shader for the sky diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl index 267ef36d4d..3eac63076c 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  //////////////////////////////////////////////////////////////////////////  // The vertex shader for creating the atmospheric sky diff --git a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl index a658edd21f..6570dcb608 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform vec4 gamma; diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl index 77ca4868a6..d14c638130 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  /////////////////////////////////////////////////////////////////////////  // The fragment shader for the sky diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl index 03bca8f27e..1ea00f723a 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  // SKY ////////////////////////////////////////////////////////////////////////  // The vertex shader for creating the atmospheric sky diff --git a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl index 7f1ad4d5b4..28381482c1 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl @@ -5,8 +5,6 @@   * $/LicenseInfo$   */ -#version 120 -  //////////////////////////////////////////////////////////  // The fragment shader for the terrain atmospherics  ////////////////////////////////////////////////////////// diff --git a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl b/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl index a003e2a1f1..3d970d252c 100644 --- a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl +++ b/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);  mat4 getSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl index fc370ef367..498fee7c66 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2DRect giLightMap; diff --git a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl index ae57227fe5..eebe930666 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec2 vary_fragcoord;  uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class3/deferred/giF.glsl b/indra/newview/app_settings/shaders/class3/deferred/giF.glsl index 951e3e97ae..9896f8dafe 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class3/deferred/giFinalF.glsl b/indra/newview/app_settings/shaders/class3/deferred/giFinalF.glsl index b2f8b2c633..df4c6b3e0a 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giFinalF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giFinalF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class3/deferred/giFinalV.glsl b/indra/newview/app_settings/shaders/class3/deferred/giFinalV.glsl index 19c4e07b8b..7e20d71529 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giFinalV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giFinalV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec2 vary_fragcoord;  uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class3/deferred/giV.glsl b/indra/newview/app_settings/shaders/class3/deferred/giV.glsl index 8dc1410ea5..e86f2896da 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec2 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl index 5f3bf68b24..980def6443 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl b/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl index a24eda35dc..9afeac6ddf 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec2 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl index ab99a88971..6d4c20f68c 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl b/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl index 12983baa94..876f65ee3a 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec2 vary_fragcoord;  uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl index f037754708..fc65881680 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl b/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl index ae57227fe5..eebe930666 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  varying vec2 vary_fragcoord;  uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index ce32f66000..d38d33cc21 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl index 8f0bcca76b..745cc01992 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl index c54d9a1e3e..de7e038402 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl index 04533fdce1..92347a5b4a 100644 --- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da);  vec3 calcPointLightSpecular(inout vec4 specular, vec3 view, vec3 v, vec3 n, vec3 l, float r, float pw, vec3 lightCol); diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl index 73bc18b866..24bbc0a1a1 100644 --- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl +++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl @@ -5,7 +5,7 @@   * $/LicenseInfo$   */ -#version 120 +  float calcDirectionalLight(vec3 n, vec3 l);  float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight); diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index dd8a88e558..4da155efda 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 27 +version 29  // NOTE: This is mostly identical to featuretable_mac.txt with a few differences  // Should be combined into one table @@ -48,6 +48,7 @@ RenderTransparentWater		1	1  RenderTreeLODFactor			1	1.0  RenderUseImpostors			1	1  RenderVBOEnable				1	1 +RenderVBOMappingDisable		1	1  RenderVolumeLODFactor		1	2.0  UseStartScreen				1	1  UseOcclusion				1	1 @@ -64,6 +65,7 @@ RenderDeferredSSAO			1	1  RenderShadowDetail			1	2  WatchdogDisabled				1	1  RenderUseStreamVBO			1	1 +RenderFSAASamples			1	16  //  // Low Graphics Settings @@ -95,6 +97,7 @@ SkyUseClassicClouds			1	0  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	0  //  // Mid Graphics Settings @@ -124,6 +127,7 @@ WLSkyDetail					1	48  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	0  //  // High Graphics Settings (purty) @@ -153,6 +157,7 @@ WLSkyDetail					1	48  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	4  //  // Ultra graphics (REALLY PURTY!) @@ -181,6 +186,8 @@ WLSkyDetail					1	128  RenderDeferred				1	1  RenderDeferredSSAO			1	1  RenderShadowDetail			1	2 +RenderFSAASamples			1	8 +  //  // Class Unknown Hardware (unknown) @@ -238,6 +245,12 @@ RenderDeferred				0	0  RenderDeferredSSAO			0	0  RenderShadowDetail			0	0 +// +// No GL_ARB_map_buffer_range +// +list NoMapBufferRange +RenderVBOMappingDisable		1	0 +  //  // "Default" setups for safe, low, medium, high @@ -467,7 +480,6 @@ RenderAvatarCloth			0	0  list ATI  RenderUseStreamVBO			1	0 -RenderAvatarVP				1	0  // Disable vertex buffer objects by default for ATI cards with little video memory  list ATIVramLT256 diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index 058bdcc730..dab73dc3d1 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -1,4 +1,4 @@ -version 23 +version 25  // NOTE: This is mostly identical to featuretable_mac.txt with a few differences  // Should be combined into one table @@ -48,6 +48,7 @@ RenderTransparentWater		1	1  RenderTreeLODFactor			1	1.0  RenderUseImpostors			1	1  RenderVBOEnable				1	1 +RenderVBOMappingDisable		1	1  RenderVolumeLODFactor		1	2.0  UseStartScreen				1	1  UseOcclusion				1	1 @@ -62,6 +63,7 @@ RenderShaderLightingMaxLevel		1	3  RenderDeferred				1	1  RenderDeferredSSAO			1	1  RenderShadowDetail			1	2 +RenderFSAASamples			1	16  //  // Low Graphics Settings @@ -93,6 +95,7 @@ SkyUseClassicClouds			1	0  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	0  //  // Mid Graphics Settings @@ -122,6 +125,7 @@ WLSkyDetail					1	48  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	0  //  // High Graphics Settings (purty) @@ -151,6 +155,7 @@ WLSkyDetail					1	48  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	4  //  // Ultra graphics (REALLY PURTY!) @@ -180,6 +185,7 @@ WLSkyDetail					1	128  RenderDeferred				1	1  RenderDeferredSSAO			1	1  RenderShadowDetail			1	2 +RenderFSAASamples			1	8  //  // Class Unknown Hardware (unknown) @@ -237,6 +243,13 @@ RenderDeferred				0	0  RenderDeferredSSAO			0	0  RenderShadowDetail			0	0 +// +// No GL_ARB_map_buffer_range +// +list NoMapBufferRange +RenderVBOMappingDisable		1	0 + +  // "Default" setups for safe, low, medium, high  // diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index e2b979d9e9..a1e25aae08 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 23 +version 26  // NOTE: This is mostly identical to featuretable_mac.txt with a few differences  // Should be combined into one table @@ -48,6 +48,7 @@ RenderTransparentWater			1	1  RenderTreeLODFactor				1	1.0  RenderUseImpostors				1	1  RenderVBOEnable					1	1 +RenderVBOMappingDisable		1	1  RenderVolumeLODFactor			1	2.0  UseStartScreen				1	1  UseOcclusion					1	1 @@ -64,6 +65,7 @@ RenderDeferredSSAO			1	1  RenderShadowDetail			1	2  WatchdogDisabled				1	1  RenderUseStreamVBO			1	1 +RenderFSAASamples			1	16  //  // Low Graphics Settings @@ -95,6 +97,7 @@ SkyUseClassicClouds			1	0  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	0  //  // Mid Graphics Settings @@ -124,6 +127,7 @@ WLSkyDetail					1	48  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	0  //  // High Graphics Settings (purty) @@ -153,6 +157,7 @@ WLSkyDetail					1	48  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	2 +RenderFSAASamples			1	4  //  // Ultra graphics (REALLY PURTY!) @@ -182,6 +187,7 @@ WLSkyDetail					1	128  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	2 +RenderFSAASamples			1	8  //  // Class Unknown Hardware (unknown) @@ -240,6 +246,13 @@ RenderDeferredSSAO			0	0  RenderShadowDetail			0	0  // +// No GL_ARB_map_buffer_range +// +list NoMapBufferRange +RenderVBOMappingDisable		1	0 + + +//  // "Default" setups for safe, low, medium, high  //  list safe @@ -412,31 +425,6 @@ Disregard128DefaultDrawDistance	1	0  list ATI_Mobility_Radeon_X1xxx  Disregard128DefaultDrawDistance	1	0 - - - -// Avatar hardware skinning causes -// invisible avatars on HD 2600... so I masked -// out other possible bad ones till it's fixed - -list ATI_Radeon_HD_2300 -RenderAvatarVP				0	0 -RenderAvatarCloth			0	0 -Disregard128DefaultDrawDistance	1	0 -list ATI_Radeon_HD_2400 -RenderAvatarVP				0	0 -RenderAvatarCloth			0	0 -Disregard128DefaultDrawDistance	1	0 -list ATI_Radeon_HD_2600 -RenderAvatarVP				0	0 -RenderAvatarCloth			0	0 -list ATI_Radeon_HD_2900 -RenderAvatarVP				0	0 -RenderAvatarCloth			0	0 -list ATI_Radeon_HD_3800 -RenderAvatarVP				0	0 -RenderAvatarCloth			0	0 -  /// Tweaked NVIDIA  list NVIDIA_GeForce_FX_5100 diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt index 3339172a1a..abe4ec9928 100644 --- a/indra/newview/featuretable_xp.txt +++ b/indra/newview/featuretable_xp.txt @@ -1,4 +1,4 @@ -version 27 +version 29  // NOTE: This is mostly identical to featuretable_mac.txt with a few differences  // Should be combined into one table @@ -48,6 +48,7 @@ RenderTransparentWater		1	1  RenderTreeLODFactor			1	1.0  RenderUseImpostors			1	1  RenderVBOEnable				1	1 +RenderVBOMappingDisable		1	1  RenderVolumeLODFactor		1	2.0  UseStartScreen				1	1  UseOcclusion				1	1 @@ -64,6 +65,7 @@ RenderDeferredSSAO			1	0  RenderShadowDetail			1	0  WatchdogDisabled				1	1  RenderUseStreamVBO			1	1 +RenderFSAASamples			1	16  //  // Low Graphics Settings @@ -95,6 +97,7 @@ SkyUseClassicClouds			1	0  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	0  //  // Mid Graphics Settings @@ -124,6 +127,7 @@ WLSkyDetail					1	48  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	0  //  // High Graphics Settings (purty) @@ -153,6 +157,7 @@ WLSkyDetail					1	48  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	2 +RenderFSAASamples			1	4  //  // Ultra graphics (REALLY PURTY!) @@ -182,6 +187,7 @@ WLSkyDetail					1	128  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	2 +RenderFSAASamples			1	8  //  // Class Unknown Hardware (unknown) @@ -240,6 +246,13 @@ RenderDeferredSSAO			0	0  RenderShadowDetail			0	0  // +// No GL_ARB_map_buffer_range +// +list NoMapBufferRange +RenderVBOMappingDisable		1	0 + + +//  // "Default" setups for safe, low, medium, high  //  list safe @@ -466,7 +479,6 @@ RenderAvatarCloth			0	0  list ATI  RenderUseStreamVBO			1	0 -RenderAvatarVP				1	0  // Disable vertex buffer objects by default for ATI cards with little video memory  list ATIVramLT256 diff --git a/indra/newview/llaccountingquotamanager.cpp b/indra/newview/llaccountingquotamanager.cpp index 0a171959e7..a4f5de5632 100644 --- a/indra/newview/llaccountingquotamanager.cpp +++ b/indra/newview/llaccountingquotamanager.cpp @@ -71,12 +71,10 @@ public:  			return;  		} -		//Differentiate what the incoming caps could be from the data -		//bool VOContent  = content.has("Objects"); +		//Differentiate what the incoming caps could be from the data	  		bool containsParcel    = content.has("parcel");  		bool containsSelection = content.has("selected"); -		//bool VORegion   = content.has("region"); -				 +					  		//Loop over the stored object ids checking against the incoming data  		for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter )  		{ @@ -91,16 +89,17 @@ public:  					for(S32 i = 0; i < dataCount; i++)  					{  						//prep#todo verify that this is safe, otherwise just add a bool -						S32 parcelId = 0; -						S32 parcelOwner = 0; +						LLUUID parcelId; +						//S32 parcelOwner = 0;  						if ( content["parcel"][i].has("parcel_id") )  						{ -							parcelId = content["parcel"][i]["parcel_id"].asInteger(); -						} -						if ( content["parcel"][i].has("parcel_owner") ) -						{ -							parcelOwner = content["parcel"][i]["parcel_owner"].asInteger(); +							parcelId = content["parcel"][i]["parcel_id"].asUUID();  						} +						 +						//if ( content["parcel"][i].has("parcel_owner") ) +						//{ +						//	parcelOwner = content["parcel"][i]["parcel_owner"].asInteger(); +						//}  						F32 ownerRenderCost		= 0;  						F32 ownerPhysicsCost	= 0; @@ -117,48 +116,69 @@ public:  						F32 otherNetworkCost	= 0;  						F32 otherSimulationCost = 0; -						F32 totalRenderCost		= 0; -						F32 totalPhysicsCost	= 0; -						F32 totalNetworkCost	= 0; -						F32 totalSimulationCost = 0; +						F32 tempRenderCost		= 0; +						F32 tempPhysicsCost		= 0; +						F32 tempNetworkCost		= 0; +						F32 tempSimulationCost  = 0; +						 +						F32 selectedRenderCost		= 0; +						F32 selectedPhysicsCost		= 0; +						F32 selectedNetworkCost		= 0; +						F32 selectedSimulationCost  = 0; +						F32 parcelCapacity			= 0; + +						if ( content["parcel"][i].has("capacity") ) +						{ +							parcelCapacity =  content["parcel"][i].has("capacity"); +						} +  						if ( content["parcel"][i].has("owner") )  						{ -							ownerRenderCost		= content["parcel"][i]["owner"]["render"].asReal(); +							ownerRenderCost		= content["parcel"][i]["owner"]["rendering"].asReal();  							ownerPhysicsCost	= content["parcel"][i]["owner"]["physics"].asReal(); -							ownerNetworkCost	= content["parcel"][i]["owner"]["network"].asReal(); -							ownerSimulationCost = content["parcel"][i]["owner"]["simulation"].asReal(); -							 +							ownerNetworkCost	= content["parcel"][i]["owner"]["streaming"].asReal(); +							ownerSimulationCost = content["parcel"][i]["owner"]["simulation"].asReal();							  						} +  						if ( content["parcel"][i].has("group") )  						{ -							groupRenderCost		= content["parcel"][i]["group"]["render"].asReal(); +							groupRenderCost		= content["parcel"][i]["group"]["rendering"].asReal();  							groupPhysicsCost	= content["parcel"][i]["group"]["physics"].asReal(); -							groupNetworkCost	= content["parcel"][i]["group"]["network"].asReal(); +							groupNetworkCost	= content["parcel"][i]["group"]["streaming"].asReal();  							groupSimulationCost = content["parcel"][i]["group"]["simulation"].asReal();  						}  						if ( content["parcel"][i].has("other") )  						{ -							otherRenderCost		= content["parcel"][i]["other"]["render"].asReal(); +							otherRenderCost		= content["parcel"][i]["other"]["rendering"].asReal();  							otherPhysicsCost	= content["parcel"][i]["other"]["physics"].asReal(); -							otherNetworkCost	= content["parcel"][i]["other"]["network"].asReal(); +							otherNetworkCost	= content["parcel"][i]["other"]["streaming"].asReal();  							otherSimulationCost = content["parcel"][i]["other"]["simulation"].asReal();  						} -						if ( content["parcel"][i].has("total") ) +						if ( content["parcel"][i].has("temp") )  						{ -							totalRenderCost		= content["parcel"][i]["total"]["render"].asReal(); -							totalPhysicsCost	= content["parcel"][i]["total"]["physics"].asReal(); -							totalNetworkCost	= content["parcel"][i]["total"]["network"].asReal(); -							totalSimulationCost = content["parcel"][i]["total"]["simulation"].asReal(); -							 +							tempRenderCost		= content["parcel"][i]["total"]["rendering"].asReal(); +							tempPhysicsCost		= content["parcel"][i]["total"]["physics"].asReal(); +							tempNetworkCost		= content["parcel"][i]["total"]["streaming"].asReal(); +							tempSimulationCost  = content["parcel"][i]["total"]["simulation"].asReal();							 +						} + +						if ( content["parcel"][i].has("selected") ) +						{ +							selectedRenderCost		= content["parcel"][i]["total"]["rendering"].asReal(); +							selectedPhysicsCost		= content["parcel"][i]["total"]["physics"].asReal(); +							selectedNetworkCost		= content["parcel"][i]["total"]["streaming"].asReal(); +							selectedSimulationCost  = content["parcel"][i]["total"]["simulation"].asReal();							  						} -						ParcelQuota parcelQuota( ownerRenderCost, ownerPhysicsCost, ownerNetworkCost, ownerSimulationCost, -												 groupRenderCost, groupPhysicsCost, groupNetworkCost, groupSimulationCost, -												 otherRenderCost, otherPhysicsCost, otherNetworkCost, otherSimulationCost, -												 totalRenderCost, totalPhysicsCost, totalNetworkCost, totalSimulationCost ); +						ParcelQuota parcelQuota( ownerRenderCost,	 ownerPhysicsCost,	  ownerNetworkCost,    ownerSimulationCost, +												 groupRenderCost,	 groupPhysicsCost,	  groupNetworkCost,    groupSimulationCost, +												 otherRenderCost,	 otherPhysicsCost,	  otherNetworkCost,    otherSimulationCost, +												 tempRenderCost,	 tempPhysicsCost,	  tempNetworkCost,	   tempSimulationCost, +												 selectedRenderCost, selectedPhysicsCost, selectedNetworkCost, selectedSimulationCost, +												 parcelCapacity );  						//Update the Parcel						  						LLParcel* pParcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();  						if ( pParcel ) @@ -179,18 +199,18 @@ public:  					F32 networkCost		= 0;  					F32 simulationCost	= 0; -					S32 localId = 0; +					LLUUID objectId; -					localId			= content["selected"][i]["local_id"].asInteger(); -					renderCost		= content["selected"][i]["render"].asReal(); +					objectId		= content["selected"][i]["local_id"].asUUID(); +					renderCost		= content["selected"][i]["rendering"].asReal();  					physicsCost		= content["selected"][i]["physics"].asReal(); -					networkCost		= content["selected"][i]["network"].asReal(); +					networkCost		= content["selected"][i]["streaming"].asReal();  					simulationCost	= content["selected"][i]["simulation"].asReal(); -					SelectionQuota selectionQuota( localId, renderCost, physicsCost, networkCost, simulationCost ); +					SelectionQuota selectionQuota( objectId, renderCost, physicsCost, networkCost, simulationCost );  					//Update the objects					 -					//gObjectList.updateQuota( localId, selectionQuota );  +					gObjectList.updateQuota( objectId, selectionQuota );   				}  			} diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 80085dad9d..c30d3b9aa3 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -392,11 +392,9 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi  	}  	LLQuaternion inv_obj_rot = ~obj_rot; // get inverse of rotation -	LLVector3 object_extents;	 +	LLVector3 object_extents = object->getScale();	  	const LLVector4a* oe4 = object->mDrawable->getSpatialExtents(); -	LLVector4a size; -	size.setSub(oe4[1], oe4[0]); -	object_extents.set( size[0], size[1], size[2] ); +	object_extents.set( oe4[1][0], oe4[1][1], oe4[1][2] );  	// make sure they object extents are non-zero  	object_extents.clamp(0.001f, F32_MAX); diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index c08771c5e7..d7ba4ea470 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -384,18 +384,18 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)  		// Continuing the horrible hack above, we need to extract the originally requested permissions data, if any,  		// and use them for each next file to be uploaded. Note the requested perms are not the same as the  		U32 everyone_perms = -			content.has("everyone_mask") ? -			content["everyone_mask"].asInteger() : +			content.has("new_everyone_mask") ? +			content["new_everyone_mask"].asInteger() :  			PERM_NONE;  		U32 group_perms = -			content.has("group_mask") ? -			content["group_mask"].asInteger() : +			content.has("new_group_mask") ? +			content["new_group_mask"].asInteger() :  			PERM_NONE;  		U32 next_owner_perms = -			content.has("next_owner_mask") ? -			content["next_owner_mask"].asInteger() : +			content.has("new_next_owner_mask") ? +			content["new_next_owner_mask"].asInteger() :  			PERM_NONE;  		std::string display_name = LLStringUtil::null; diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index bdc12ec0e3..ad3710843c 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -94,7 +94,9 @@ void LLDrawable::init()  	mRenderType = 0;  	mCurrentScale = LLVector3(1,1,1);  	mDistanceWRTCamera = 0.0f; - +	mPositionGroup.clear(); +	mExtents[0].clear(); +	mExtents[1].clear();  	mQuietCount = 0;  	mState     = 0; @@ -587,7 +589,10 @@ void LLDrawable::setRadius(F32 radius)  void LLDrawable::moveUpdatePipeline(BOOL moved)  { -	makeActive(); +	if (moved) +	{ +		makeActive(); +	}  	// Update the face centers.  	for (S32 i = 0; i < getNumFaces(); i++) @@ -695,7 +700,8 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)  {  	if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)  	{ -		llerrs << "WTF?" << llendl; +		llwarns << "Attempted to update distance for non-world camera." << llendl; +		return;  	}  	//switch LOD with the spatial group to avoid artifacts diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 9ebe1a45b4..e268640a21 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -276,6 +276,7 @@ public:  		REBUILD_SHADOW =  0x02000000,  		HAS_ALPHA		= 0x04000000,  		RIGGED			= 0x08000000, +		PARTITION_MOVE	= 0x10000000,  	} EDrawableFlags;  private: //aligned members diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 25e4bc847c..f5483d969d 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -191,6 +191,16 @@ void LLDrawPool::renderPostDeferred(S32 pass)  //virtual  void LLDrawPool::endRenderPass( S32 pass )  { +	for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++) +	{ //dummy cleanup of any currently bound textures +		if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE) +		{ +			gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType()); +			gGL.getTexUnit(i)->disable(); +		} +	} + +	gGL.getTexUnit(0)->activate();  }  //virtual  @@ -430,14 +440,14 @@ void LLRenderPass::renderTexture(U32 type, U32 mask)  	pushBatches(type, mask, TRUE);  } -void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture) +void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)  {  	for (LLCullResult::drawinfo_list_t::iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)	  	{  		LLDrawInfo* pparams = *i;  		if (pparams)   		{ -			pushBatch(*pparams, mask, texture); +			pushBatch(*pparams, mask, texture, batch_textures);  		}  	}  } @@ -456,26 +466,43 @@ void LLRenderPass::applyModelMatrix(LLDrawInfo& params)  	}  } -void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) +void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)  {  	applyModelMatrix(params); +	bool tex_setup = false; +  	if (texture)  	{ -		if (params.mTexture.notNull()) +		if (batch_textures && params.mTextureList.size() > 1)  		{ -			params.mTexture->addTextureStats(params.mVSize); -			gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ; -			if (params.mTextureMatrix) +			for (U32 i = 0; i < params.mTextureList.size(); ++i)  			{ -				glMatrixMode(GL_TEXTURE); -				glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); -				gPipeline.mTextureMatrixOps++; +				if (params.mTextureList[i].notNull()) +				{ +					gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE); +				}  			}  		}  		else -		{ -			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +		{ //not batching textures or batch has only 1 texture -- might need a texture matrix +			if (params.mTexture.notNull()) +			{ +				params.mTexture->addTextureStats(params.mVSize); +				gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ; +				if (params.mTextureMatrix) +				{ +					tex_setup = true; +					gGL.getTexUnit(0)->activate(); +					glMatrixMode(GL_TEXTURE); +					glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); +					gPipeline.mTextureMatrixOps++; +				} +			} +			else +			{ +				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +			}  		}  	} @@ -490,7 +517,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)  		gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);  	} -	if (params.mTextureMatrix && texture && params.mTexture.notNull()) +	if (tex_setup)  	{  		glLoadIdentity();  		glMatrixMode(GL_MODELVIEW); diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index d3fd9ead0d..c7acbb42c6 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -146,8 +146,8 @@ public:  	void resetDrawOrders() { }  	static void applyModelMatrix(LLDrawInfo& params); -	virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE); -	virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture); +	virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE); +	virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);  	virtual void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);  	virtual void renderGroups(U32 type, U32 mask, BOOL texture = TRUE);  	virtual void renderTexture(U32 type, U32 mask); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 8b5a2ce781..8d46133912 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -124,7 +124,10 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)  	if (pass == 0)  	{  		simple_shader = &gDeferredAlphaProgram; -		fullbright_shader = &gDeferredFullbrightProgram; +		fullbright_shader = &gObjectFullbrightProgram; + +		//prime simple shader (loads shadow relevant uniforms) +		gPipeline.bindDeferredShader(*simple_shader);  	}  	else  	{ @@ -228,13 +231,13 @@ void LLDrawPoolAlpha::render(S32 pass)  			if (!LLPipeline::sRenderDeferred)  			{  				simple_shader->bind(); -				pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask()); +				pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);  			}  			if (fullbright_shader)  			{  				fullbright_shader->bind();  			} -			pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask()); +			pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);  			LLGLSLShader::bindNoShader();  		}  		else @@ -273,7 +276,14 @@ void LLDrawPoolAlpha::render(S32 pass)  		}  	} -	renderAlpha(getVertexDataMask()); +	if (mVertexShaderLevel > 0) +	{ +		renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX); +	} +	else +	{ +		renderAlpha(getVertexDataMask()); +	}  	gGL.setColorMask(true, false); @@ -283,11 +293,6 @@ void LLDrawPoolAlpha::render(S32 pass)  		gGL.setSceneBlendType(LLRender::BT_ALPHA);  	} -	if (deferred_render && current_shader != NULL) -	{ -		gPipeline.unbindDeferredShader(*current_shader); -	} -  	if (sShowDebugAlpha)  	{  		if(gPipeline.canUseWindLightShaders())  @@ -339,12 +344,9 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  {  	BOOL initialized_lighting = FALSE;  	BOOL light_enabled = TRUE; -	S32 diffuse_channel = 0; - -	BOOL use_shaders = (LLPipeline::sUnderWaterRender && gPipeline.canUseVertexShaders()) -		|| gPipeline.canUseWindLightShadersOnObjects(); -	 +	BOOL use_shaders = gPipeline.canUseVertexShaders(); +		  	for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)  	{  		LLSpatialGroup* group = *i; @@ -368,92 +370,89 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  				LLRenderPass::applyModelMatrix(params); +				 +				if (params.mFullbright)  				{ -					if (params.mFullbright) -					{ -						// Turn off lighting if it hasn't already been so. -						if (light_enabled || !initialized_lighting) -						{ -							initialized_lighting = TRUE; -							if (use_shaders)  -							{ -								target_shader = fullbright_shader; -							} -							else -							{ -								gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); -							} -							light_enabled = FALSE; -						} -					} -					// Turn on lighting if it isn't already. -					else if (!light_enabled || !initialized_lighting) +					// Turn off lighting if it hasn't already been so. +					if (light_enabled || !initialized_lighting)  					{  						initialized_lighting = TRUE;  						if (use_shaders)   						{ -							target_shader = simple_shader; +							target_shader = fullbright_shader;  						}  						else  						{ -							gPipeline.enableLightsDynamic(); +							gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));  						} -						light_enabled = TRUE; +						light_enabled = FALSE;  					} - -					// If we need shaders, and we're not ALREADY using the proper shader, then bind it -					// (this way we won't rebind shaders unnecessarily). -					if(use_shaders && (current_shader != target_shader)) +				} +				// Turn on lighting if it isn't already. +				else if (!light_enabled || !initialized_lighting) +				{ +					initialized_lighting = TRUE; +					if (use_shaders)   					{ -						llassert(target_shader != NULL); -						if (deferred_render && current_shader != NULL) -						{ -							gPipeline.unbindDeferredShader(*current_shader); -							diffuse_channel = 0; -						} -						current_shader = target_shader; -						if (deferred_render) -						{ -							gPipeline.bindDeferredShader(*current_shader); -							diffuse_channel = current_shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); -						} -						else -						{ -							current_shader->bind(); -						} +						target_shader = simple_shader;  					} -					else if (!use_shaders && current_shader != NULL) +					else  					{ -						if (deferred_render) -						{ -							gPipeline.unbindDeferredShader(*current_shader); -							diffuse_channel = 0; -						} -						LLGLSLShader::bindNoShader(); -						current_shader = NULL; +						gPipeline.enableLightsDynamic();  					} +					light_enabled = TRUE; +				} -					if (params.mGroup) -					{ -						params.mGroup->rebuildMesh(); -					} +				// If we need shaders, and we're not ALREADY using the proper shader, then bind it +				// (this way we won't rebind shaders unnecessarily). +				if(use_shaders && (current_shader != target_shader)) +				{ +					llassert(target_shader != NULL); +					current_shader = target_shader; +					current_shader->bind(); +				} +				else if (!use_shaders && current_shader != NULL) +				{ +					LLGLSLShader::bindNoShader(); +					current_shader = NULL; +				} -					 -					if (params.mTexture.notNull()) +				if (params.mGroup) +				{ +					params.mGroup->rebuildMesh(); +				} + +				bool tex_setup = false; + +				if (use_shaders && params.mTextureList.size() > 1) +				{ +					for (U32 i = 0; i < params.mTextureList.size(); ++i)  					{ -						gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get()); -						if(params.mTexture.notNull()) +						if (params.mTextureList[i].notNull())  						{ -							params.mTexture->addTextureStats(params.mVSize); +							gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE);  						} +					} +				} +				else +				{ //not batching textures or batch has only 1 texture -- might need a texture matrix +					if (params.mTexture.notNull()) +					{ +						params.mTexture->addTextureStats(params.mVSize); +						gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;  						if (params.mTextureMatrix)  						{ +							tex_setup = true;  							gGL.getTexUnit(0)->activate();  							glMatrixMode(GL_TEXTURE);  							glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);  							gPipeline.mTextureMatrixOps++;  						}  					} +					else +					{ +						gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +					}  				}  				params.mVertexBuffer->setBuffer(mask); @@ -480,7 +479,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  					gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);  				} -				if (params.mTextureMatrix && params.mTexture.notNull()) +				if (tex_setup)  				{  					gGL.getTexUnit(0)->activate();  					glLoadIdentity(); @@ -490,15 +489,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  		}  	} -	if (deferred_render && current_shader != NULL) -	{ -		gPipeline.unbindDeferredShader(*current_shader); -		LLVertexBuffer::unbind();	 -		LLGLState::checkStates(); -		LLGLState::checkTextureChannels(); -		LLGLState::checkClientArrays(); -	} -	 +	LLVertexBuffer::unbind();	 +		  	if (!light_enabled)  	{  		gPipeline.enableLightsDynamic(); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 645c7ebcae..9f790d03fe 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -459,14 +459,6 @@ S32 LLDrawPoolAvatar::getNumPasses()  	{  		return 10;  	} -	if (LLPipeline::sImpostorRender) -	{ -		return 1; -	} -	else  -	{ -		return 3; -	}  } @@ -613,11 +605,11 @@ void LLDrawPoolAvatar::beginRigid()  	{  		if (LLPipeline::sUnderWaterRender)  		{ -			sVertexProgram = &gObjectSimpleWaterProgram; +			sVertexProgram = &gObjectSimpleNonIndexedWaterProgram;  		}  		else  		{ -			sVertexProgram = &gObjectSimpleProgram; +			sVertexProgram = &gObjectSimpleNonIndexedProgram;  		}  		if (sVertexProgram != NULL) @@ -669,7 +661,7 @@ void LLDrawPoolAvatar::endDeferredImpostor()  void LLDrawPoolAvatar::beginDeferredRigid()  { -	sVertexProgram = &gDeferredDiffuseProgram; +	sVertexProgram = &gDeferredNonIndexedDiffuseProgram;  	sVertexProgram->bind();  } @@ -700,11 +692,11 @@ void LLDrawPoolAvatar::beginSkinned()  	{  		if (LLPipeline::sUnderWaterRender)  		{ -			sVertexProgram = &gObjectSimpleWaterProgram; +			sVertexProgram = &gObjectSimpleNonIndexedWaterProgram;  		}  		else  		{ -			sVertexProgram = &gObjectSimpleProgram; +			sVertexProgram = &gObjectSimpleNonIndexedProgram;  		}  	} @@ -789,11 +781,11 @@ void LLDrawPoolAvatar::beginRiggedSimple()  	{  		if (LLPipeline::sUnderWaterRender)  		{ -			sVertexProgram = &gObjectSimpleWaterProgram; +			sVertexProgram = &gObjectSimpleNonIndexedWaterProgram;  		}  		else  		{ -			sVertexProgram = &gObjectSimpleProgram; +			sVertexProgram = &gObjectSimpleNonIndexedProgram;  		}  	} @@ -864,11 +856,11 @@ void LLDrawPoolAvatar::beginRiggedFullbright()  	{  		if (LLPipeline::sUnderWaterRender)  		{ -			sVertexProgram = &gObjectFullbrightWaterProgram; +			sVertexProgram = &gObjectFullbrightNonIndexedWaterProgram;  		}  		else  		{ -			sVertexProgram = &gObjectFullbrightProgram; +			sVertexProgram = &gObjectFullbrightNonIndexedProgram;  		}  	} @@ -908,11 +900,11 @@ void LLDrawPoolAvatar::beginRiggedShinySimple()  	{  		if (LLPipeline::sUnderWaterRender)  		{ -			sVertexProgram = &gObjectShinyWaterProgram; +			sVertexProgram = &gObjectShinyNonIndexedWaterProgram;  		}  		else  		{ -			sVertexProgram = &gObjectShinyProgram; +			sVertexProgram = &gObjectShinyNonIndexedProgram;  		}  	} @@ -953,11 +945,11 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()  	{  		if (LLPipeline::sUnderWaterRender)  		{ -			sVertexProgram = &gObjectFullbrightShinyWaterProgram; +			sVertexProgram = &gObjectFullbrightShinyNonIndexedWaterProgram;  		}  		else  		{ -			sVertexProgram = &gObjectFullbrightShinyProgram; +			sVertexProgram = &gObjectFullbrightShinyNonIndexedProgram;  		}  	} @@ -1419,7 +1411,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*  void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  { -	if (avatar->isSelf() && !gAgent.needsRenderAvatar()) +	if (avatar->isSelf() && !gAgent.needsRenderAvatar() || !gMeshRepo.meshRezEnabled())  	{  		return;  	} @@ -1456,7 +1448,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  			continue;  		} -		const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(mesh_id); +		const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(mesh_id, vobj);  		if (!skin)  		{  			continue; diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 2f76baaaf7..813b3820ee 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -316,6 +316,9 @@ void LLDrawPoolBump::endRenderPass(S32 pass)  			llassert(0);  			break;  	} + +	//to cleanup texture channels +	LLRenderPass::endRenderPass(pass);  }  //static @@ -354,6 +357,11 @@ void LLDrawPoolBump::beginShiny(bool invisible)  	}  	bindCubeMap(shader, mVertexShaderLevel, diffuse_channel, cube_channel, invisible); + +	if (mVertexShaderLevel > 1) +	{ //indexed texture rendering, channel 0 is always diffuse +		diffuse_channel = 0; +	}  }  //static @@ -421,16 +429,16 @@ void LLDrawPoolBump::renderShiny(bool invisible)  		LLGLEnable blend_enable(GL_BLEND);  		if (!invisible && mVertexShaderLevel > 1)  		{ -			LLRenderPass::renderTexture(LLRenderPass::PASS_SHINY, sVertexMask); +			LLRenderPass::pushBatches(LLRenderPass::PASS_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);  		}  		else if (!invisible)  		{  			renderGroups(LLRenderPass::PASS_SHINY, sVertexMask);  		} -		else // invisible -		{ -			renderGroups(LLRenderPass::PASS_INVISI_SHINY, sVertexMask); -		} +		//else // invisible (deprecated) +		//{ +			//renderGroups(LLRenderPass::PASS_INVISI_SHINY, sVertexMask); +		//}  	}  } @@ -529,6 +537,12 @@ void LLDrawPoolBump::beginFullbrightShiny()  		gGL.getTexUnit(cube_channel)->bind(cube_map);  		gGL.getTexUnit(0)->activate();  	} + +	if (mVertexShaderLevel > 1) +	{ //indexed texture rendering, channel 0 is always diffuse +		diffuse_channel = 0; +	} +  	mShiny = TRUE;  } @@ -543,7 +557,15 @@ void LLDrawPoolBump::renderFullbrightShiny()  	if( gSky.mVOSkyp->getCubeMap() )  	{  		LLGLEnable blend_enable(GL_BLEND); -		LLRenderPass::renderTexture(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask); + +		if (mVertexShaderLevel > 1) +		{ +			LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +		} +		else +		{ +			LLRenderPass::renderTexture(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask); +		}  	}  } @@ -843,6 +865,9 @@ void LLDrawPoolBump::endPostDeferredPass(S32 pass)  		endBump(LLRenderPass::PASS_POST_BUMP);  		break;  	} + +	//to disable texture channels +	LLRenderPass::endRenderPass(pass);  }  void LLDrawPoolBump::renderPostDeferred(S32 pass) @@ -1300,43 +1325,60 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)  	}  } -void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) +void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)  {  	applyModelMatrix(params); -	if (params.mTextureMatrix) +	bool tex_setup = false; + +	if (batch_textures && params.mTextureList.size() > 1)  	{ -		if (mShiny) +		for (U32 i = 0; i < params.mTextureList.size(); ++i)  		{ -			gGL.getTexUnit(0)->activate(); -			glMatrixMode(GL_TEXTURE); +			if (params.mTextureList[i].notNull()) +			{ +				gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE); +			}  		} -		else +	} +	else +	{ //not batching textures or batch has only 1 texture -- might need a texture matrix +		if (params.mTextureMatrix)  		{ -			gGL.getTexUnit(1)->activate(); -			glMatrixMode(GL_TEXTURE); +			if (mShiny) +			{ +				gGL.getTexUnit(0)->activate(); +				glMatrixMode(GL_TEXTURE); +			} +			else +			{ +				gGL.getTexUnit(1)->activate(); +				glMatrixMode(GL_TEXTURE); +				glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); +				gPipeline.mTextureMatrixOps++; +				gGL.getTexUnit(0)->activate(); +			} +  			glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);  			gPipeline.mTextureMatrixOps++; -			gGL.getTexUnit(0)->activate(); -		} - -		glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); -		gPipeline.mTextureMatrixOps++; -	} -	if (mShiny && mVertexShaderLevel > 1 && texture) -	{ -		if (params.mTexture.notNull()) -		{ -			gGL.getTexUnit(diffuse_channel)->bind(params.mTexture) ; -			params.mTexture->addTextureStats(params.mVSize);		 +			tex_setup = true;  		} -		else + +		if (mShiny && mVertexShaderLevel > 1 && texture)  		{ -			gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); +			if (params.mTexture.notNull()) +			{ +				gGL.getTexUnit(diffuse_channel)->bind(params.mTexture) ; +				params.mTexture->addTextureStats(params.mVSize);		 +			} +			else +			{ +				gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); +			}  		}  	} -	 +  	if (params.mGroup)  	{  		params.mGroup->rebuildMesh(); @@ -1344,7 +1386,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)  	params.mVertexBuffer->setBuffer(mask);  	params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);  	gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); -	if (params.mTextureMatrix) +	if (tex_setup)  	{  		if (mShiny)  		{ diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index f4702bf61d..476b1d41b7 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -55,7 +55,7 @@ public:  	virtual void endRenderPass( S32 pass );  	virtual S32	 getNumPasses();  	/*virtual*/ void prerender(); -	/*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture); +	/*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);  	void renderBump(U32 type, U32 mask);  	void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture); diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 2e83167851..5dbb27cabb 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -44,6 +44,36 @@ static LLGLSLShader* fullbright_shader = NULL;  static LLFastTimer::DeclareTimer FTM_RENDER_SIMPLE_DEFERRED("Deferred Simple");  static LLFastTimer::DeclareTimer FTM_RENDER_GRASS_DEFERRED("Deferred Grass"); +void LLDrawPoolGlow::beginPostDeferredPass(S32 pass) +{ +	gDeferredFullbrightProgram.bind(); +} + +void LLDrawPoolGlow::renderPostDeferred(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_GLOW); +	LLGLEnable blend(GL_BLEND); +	LLGLDisable test(GL_ALPHA_TEST); +	gGL.flush(); +	/// Get rid of z-fighting with non-glow pass. +	LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); +	glPolygonOffset(-1.0f, -1.0f); +	gGL.setSceneBlendType(LLRender::BT_ADD); +	 +	LLGLDepthTest depth(GL_TRUE, GL_FALSE); +	gGL.setColorMask(false, true); +	pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +	 +	gGL.setColorMask(true, false); +	gGL.setSceneBlendType(LLRender::BT_ALPHA);	 +} + +void LLDrawPoolGlow::endPostDeferredPass(S32 pass) +{ +	gDeferredFullbrightProgram.unbind(); +	LLRenderPass::endRenderPass(pass); +} +  void LLDrawPoolGlow::render(S32 pass)  {  	LLFastTimer t(FTM_RENDER_GLOW); @@ -68,7 +98,15 @@ void LLDrawPoolGlow::render(S32 pass)  	LLGLDepthTest depth(GL_TRUE, GL_FALSE);  	gGL.setColorMask(false, true); -	renderTexture(LLRenderPass::PASS_GLOW, getVertexDataMask()); + +	if (shader_level > 1) +	{ +		pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +	} +	else +	{ +		renderTexture(LLRenderPass::PASS_GLOW, getVertexDataMask()); +	}  	gGL.setColorMask(true, false);  	gGL.setSceneBlendType(LLRender::BT_ALPHA); @@ -79,10 +117,10 @@ void LLDrawPoolGlow::render(S32 pass)  	}  } -void LLDrawPoolGlow::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) +void LLDrawPoolGlow::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)  {  	glColor4ubv(params.mGlowColor.mV); -	LLRenderPass::pushBatch(params, mask, texture); +	LLRenderPass::pushBatch(params, mask, texture, batch_textures);  } @@ -126,10 +164,11 @@ void LLDrawPoolSimple::beginRenderPass(S32 pass)  void LLDrawPoolSimple::endRenderPass(S32 pass)  {  	LLFastTimer t(FTM_RENDER_SIMPLE); +	stop_glerror();  	LLRenderPass::endRenderPass(pass); - -	if (mVertexShaderLevel > 0){ - +	stop_glerror(); +	if (mVertexShaderLevel > 0) +	{  		simple_shader->unbind();  	}  } @@ -142,13 +181,24 @@ void LLDrawPoolSimple::render(S32 pass)  	{ //render simple  		LLFastTimer t(FTM_RENDER_SIMPLE);  		gPipeline.enableLightsDynamic(); -		renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask()); -		if (LLPipeline::sRenderDeferred) -		{ //if deferred rendering is enabled, bump faces aren't registered as simple -			//render bump faces here as simple so bump faces will appear under water -			renderTexture(LLRenderPass::PASS_BUMP, getVertexDataMask()); +		if (mVertexShaderLevel > 0) +		{ +			U32 mask = getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX; + +			pushBatches(LLRenderPass::PASS_SIMPLE, mask, TRUE, TRUE); + +			if (LLPipeline::sRenderDeferred) +			{ //if deferred rendering is enabled, bump faces aren't registered as simple +				//render bump faces here as simple so bump faces will appear under water +				pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE); +			} +		} +		else +		{ +			renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask());  		} +		  	}  } @@ -177,7 +227,7 @@ void LLDrawPoolSimple::renderDeferred(S32 pass)  	{ //render simple  		LLFastTimer t(FTM_RENDER_SIMPLE_DEFERRED); -		renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask()); +		pushBatches(LLRenderPass::PASS_SIMPLE, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);  	}  } @@ -200,11 +250,11 @@ void LLDrawPoolGrass::beginRenderPass(S32 pass)  	if (LLPipeline::sUnderWaterRender)  	{ -		simple_shader = &gObjectSimpleWaterProgram; +		simple_shader = &gObjectSimpleNonIndexedWaterProgram;  	}  	else  	{ -		simple_shader = &gObjectSimpleProgram; +		simple_shader = &gObjectSimpleNonIndexedProgram;  	}  	if (mVertexShaderLevel > 0) @@ -285,6 +335,26 @@ void LLDrawPoolFullbright::prerender()  	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);  } +void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass) +{ +	gDeferredFullbrightProgram.bind(); +} + +void LLDrawPoolFullbright::renderPostDeferred(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_FULLBRIGHT); +	 +	gGL.setSceneBlendType(LLRender::BT_ALPHA); +	U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; +	pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE); +} + +void LLDrawPoolFullbright::endPostDeferredPass(S32 pass) +{ +	gDeferredFullbrightProgram.unbind(); +	LLRenderPass::endRenderPass(pass); +} +  void LLDrawPoolFullbright::beginRenderPass(S32 pass)  {  	LLFastTimer t(FTM_RENDER_FULLBRIGHT); @@ -313,25 +383,21 @@ void LLDrawPoolFullbright::endRenderPass(S32 pass)  void LLDrawPoolFullbright::render(S32 pass)  { //render fullbright  	LLFastTimer t(FTM_RENDER_FULLBRIGHT); +	gGL.setSceneBlendType(LLRender::BT_ALPHA); +  	if (mVertexShaderLevel > 0)  	{  		fullbright_shader->bind();  		fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f); +		U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; +		pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE);  	}  	else  	{  		gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); +		U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR; +		renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask);  	} -	 -	//gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.25f); -	 -	//LLGLEnable test(GL_ALPHA_TEST); -	//LLGLEnable blend(GL_BLEND); -	gGL.setSceneBlendType(LLRender::BT_ALPHA); -	U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR; -	renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask); - -	//gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);  }  S32 LLDrawPoolFullbright::getNumPasses() diff --git a/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h index 5f3bbebbda..3811b3d398 100644 --- a/indra/newview/lldrawpoolsimple.h +++ b/indra/newview/lldrawpoolsimple.h @@ -98,9 +98,9 @@ public:  	LLDrawPoolFullbright();  	/*virtual*/ S32 getNumPostDeferredPasses() { return 1; } -	/*virtual*/ void beginPostDeferredPass(S32 pass) { beginRenderPass(pass); } -	/*virtual*/ void endPostDeferredPass(S32 pass) { endRenderPass(pass); } -	/*virtual*/ void renderPostDeferred(S32 pass) { render(pass); } +	/*virtual*/ void beginPostDeferredPass(S32 pass); +	/*virtual*/ void endPostDeferredPass(S32 pass); +	/*virtual*/ void renderPostDeferred(S32 pass);  	/*virtual*/ void beginRenderPass(S32 pass);  	/*virtual*/ void endRenderPass(S32 pass); @@ -126,12 +126,12 @@ public:  	virtual void prerender() { }  	/*virtual*/ S32 getNumPostDeferredPasses() { return 1; } -	/*virtual*/ void beginPostDeferredPass(S32 pass) { beginRenderPass(pass); } -	/*virtual*/ void endPostDeferredPass(S32 pass) { endRenderPass(pass); } -	/*virtual*/ void renderPostDeferred(S32 pass) { render(pass); } +	/*virtual*/ void beginPostDeferredPass(S32 pass);  +	/*virtual*/ void endPostDeferredPass(S32 pass); +	/*virtual*/ void renderPostDeferred(S32 pass);  	void render(S32 pass = 0); -	void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture = TRUE); +	void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);  }; diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 195ee60a2e..81c796b146 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -66,11 +66,11 @@ void LLDrawPoolTree::beginRenderPass(S32 pass)  	if (LLPipeline::sUnderWaterRender)  	{ -		shader = &gObjectSimpleWaterProgram; +		shader = &gObjectSimpleNonIndexedWaterProgram;  	}  	else  	{ -		shader = &gObjectSimpleProgram; +		shader = &gObjectSimpleNonIndexedProgram;  	}  	if (gPipeline.canUseWindLightShadersOnObjects()) diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 696c2d1abd..409b18d522 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -44,6 +44,8 @@ LLPointer<LLViewerTexture> LLDrawPoolWLSky::sCloudNoiseTexture = NULL;  LLPointer<LLImageRaw> LLDrawPoolWLSky::sCloudNoiseRawImage = NULL; +static LLGLSLShader* cloud_shader = NULL; +static LLGLSLShader* sky_shader = NULL;  LLDrawPoolWLSky::LLDrawPoolWLSky(void) : @@ -83,12 +85,32 @@ LLViewerTexture *LLDrawPoolWLSky::getDebugTexture()  void LLDrawPoolWLSky::beginRenderPass( S32 pass )  { +	sky_shader = +		LLPipeline::sUnderWaterRender ? +			&gObjectSimpleWaterProgram : +			&gWLSkyProgram; + +	cloud_shader = +			LLPipeline::sUnderWaterRender ? +				&gObjectSimpleWaterProgram : +				&gWLCloudProgram;  }  void LLDrawPoolWLSky::endRenderPass( S32 pass )  {  } +void LLDrawPoolWLSky::beginDeferredPass(S32 pass) +{ +	sky_shader = &gDeferredWLSkyProgram; +	cloud_shader = &gDeferredWLCloudProgram; +} + +void LLDrawPoolWLSky::endDeferredPass(S32 pass) +{ + +} +  void LLDrawPoolWLSky::renderDome(F32 camHeightLocal, LLGLSLShader * shader) const  {  	LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); @@ -128,19 +150,14 @@ void LLDrawPoolWLSky::renderSkyHaze(F32 camHeightLocal) const  {  	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))  	{ -		LLGLSLShader* shader = -			LLPipeline::sUnderWaterRender ? -				&gObjectSimpleWaterProgram : -				&gWLSkyProgram; -  		LLGLDisable blend(GL_BLEND); -		shader->bind(); +		sky_shader->bind();  		/// Render the skydome -		renderDome(camHeightLocal, shader);	 +		renderDome(camHeightLocal, sky_shader);	 -		shader->unbind(); +		sky_shader->unbind();  	}  } @@ -186,23 +203,18 @@ void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const  {  	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS))  	{ -		LLGLSLShader* shader = -			LLPipeline::sUnderWaterRender ? -				&gObjectSimpleWaterProgram : -				&gWLCloudProgram; -  		LLGLEnable blend(GL_BLEND);  		gGL.setSceneBlendType(LLRender::BT_ALPHA);  		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);  		gGL.getTexUnit(0)->bind(sCloudNoiseTexture); -		shader->bind(); +		cloud_shader->bind();  		/// Render the skydome -		renderDome(camHeightLocal, shader); +		renderDome(camHeightLocal, cloud_shader); -		shader->unbind(); +		cloud_shader->unbind();  	}  } @@ -246,6 +258,53 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()  	}  } +void LLDrawPoolWLSky::renderDeferred(S32 pass) +{ +	if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)) +	{ +		return; +	} +	LLFastTimer ftm(FTM_RENDER_WL_SKY); + +	const F32 camHeightLocal = LLWLParamManager::instance()->getDomeOffset() * LLWLParamManager::instance()->getDomeRadius(); + +	LLGLSNoFog disableFog; +	LLGLDepthTest depth(GL_TRUE, GL_FALSE); +	LLGLDisable clip(GL_CLIP_PLANE0); + +	gGL.setColorMask(true, false); + +	LLGLSquashToFarClip far_clip(glh_get_current_projection()); + +	renderSkyHaze(camHeightLocal); + +	LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); +	glPushMatrix(); + +		 +		glTranslatef(origin.mV[0], origin.mV[1], origin.mV[2]); + +		gDeferredStarProgram.bind(); +		// *NOTE: have to bind a texture here since register combiners blending in +		// renderStars() requires something to be bound and we might as well only +		// bind the moon's texture once.		 +		gGL.getTexUnit(0)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture()); + +		renderHeavenlyBodies(); + +		renderStars(); +		 +		gDeferredStarProgram.unbind(); + +	glPopMatrix(); + +	renderSkyClouds(camHeightLocal); + +	gGL.setColorMask(true, true); +	//gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + +} +  void LLDrawPoolWLSky::render(S32 pass)  {  	if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)) diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h index 8ca1ebb942..cd15c991ee 100644 --- a/indra/newview/lldrawpoolwlsky.h +++ b/indra/newview/lldrawpoolwlsky.h @@ -44,10 +44,10 @@ public:  	/*virtual*/ BOOL isDead() { return FALSE; } -	/*virtual*/ S32 getNumPostDeferredPasses() { return getNumPasses(); } -	/*virtual*/ void beginPostDeferredPass(S32 pass) { beginRenderPass(pass); } -	/*virtual*/ void endPostDeferredPass(S32 pass) { endRenderPass(pass); } -	/*virtual*/ void renderPostDeferred(S32 pass) { render(pass); } +	/*virtual*/ S32 getNumDeferredPasses() { return 1; } +	/*virtual*/ void beginDeferredPass(S32 pass); +	/*virtual*/ void endDeferredPass(S32 pass); +	/*virtual*/ void renderDeferred(S32 pass);  	/*virtual*/ LLViewerTexture *getDebugTexture();  	/*virtual*/ void beginRenderPass( S32 pass ); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 5398c13c44..b6566fcbd0 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -165,6 +165,7 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)  	mIndexInTex = 0;  	mTexture		= NULL;  	mTEOffset		= -1; +	mTextureIndex = 255;  	setDrawable(drawablep);  	mVObjp = objp; @@ -364,14 +365,7 @@ void LLFace::setSize(S32 num_vertices, S32 num_indices, bool align)  		//allocate vertices in blocks of 4 for alignment  		num_vertices = (num_vertices + 0x3) & ~0x3;  	} -	else -	{ -		if (mDrawablep->getVOVolume()) -		{ -			llerrs << "WTF?" << llendl; -		} -	} - +	  	if (mGeomCount != num_vertices ||  		mIndicesCount != num_indices)  	{ @@ -393,6 +387,26 @@ void LLFace::setGeomIndex(U16 idx)  	}  } +void LLFace::setTextureIndex(U8 index) +{ +	if (index != mTextureIndex) +	{ +		mTextureIndex = index; + +		if (mTextureIndex != 255) +		{ +			mDrawablep->setState(LLDrawable::REBUILD_POSITION); +		} +		else +		{ +			if (mDrawInfo && !mDrawInfo->mTextureList.empty()) +			{ +				llerrs << "Face with no texture index references indexed texture draw info." << llendl; +			} +		} +	} +} +  void LLFace::setIndicesIndex(S32 idx)   {   	if (mIndicesIndex != idx) @@ -415,11 +429,11 @@ U16 LLFace::getGeometryAvatar(  	if (mVertexBuffer.notNull())  	{ -		mVertexBuffer->getVertexStrider      (vertices, mGeomIndex); -		mVertexBuffer->getNormalStrider      (normals, mGeomIndex); -		mVertexBuffer->getTexCoord0Strider    (tex_coords, mGeomIndex); -		mVertexBuffer->getWeightStrider(vertex_weights, mGeomIndex); -		mVertexBuffer->getClothWeightStrider(clothing_weights, mGeomIndex); +		mVertexBuffer->getVertexStrider      (vertices, mGeomIndex, mGeomCount); +		mVertexBuffer->getNormalStrider      (normals, mGeomIndex, mGeomCount); +		mVertexBuffer->getTexCoord0Strider    (tex_coords, mGeomIndex, mGeomCount); +		mVertexBuffer->getWeightStrider(vertex_weights, mGeomIndex, mGeomCount); +		mVertexBuffer->getClothWeightStrider(clothing_weights, mGeomIndex, mGeomCount);  	}  	return mGeomIndex; @@ -432,17 +446,17 @@ U16 LLFace::getGeometry(LLStrider<LLVector3> &vertices, LLStrider<LLVector3> &no  	if (mVertexBuffer.notNull())  	{ -		mVertexBuffer->getVertexStrider(vertices,   mGeomIndex); +		mVertexBuffer->getVertexStrider(vertices,   mGeomIndex, mGeomCount);  		if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL))  		{ -			mVertexBuffer->getNormalStrider(normals,    mGeomIndex); +			mVertexBuffer->getNormalStrider(normals,    mGeomIndex, mGeomCount);  		}  		if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD0))  		{ -			mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex); +			mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount);  		} -		mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex); +		mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount);  	}  	return mGeomIndex; @@ -679,6 +693,19 @@ static void xform(LLVector2 &tex_coord, F32 cosAng, F32 sinAng, F32 offS, F32 of  } +bool less_than_max_mag(const LLVector4a& vec) +{ +	LLVector4a MAX_MAG; +	MAX_MAG.splat(1024.f*1024.f); + +	LLVector4a val; +	val.setAbs(vec); + +	S32 lt = val.lessThan(MAX_MAG).getGatheredBits() & 0x7; +	 +	return lt == 0x7; +} +  BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  								const LLMatrix4& mat_vert_in, const LLMatrix3& mat_normal_in, BOOL global_volume)  { @@ -713,6 +740,8 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  		min = face.mExtents[0];  		max = face.mExtents[1]; +		llassert(less_than_max_mag(min)); +		llassert(less_than_max_mag(max));  		//min, max are in volume space, convert to drawable render space  		LLVector4a center; @@ -724,6 +753,9 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  		size.setSub(max, min);  		size.mul(0.5f); +		llassert(less_than_max_mag(min)); +		llassert(less_than_max_mag(max)); +  		if (!global_volume)  		{  			//VECTORIZE THIS @@ -761,6 +793,8 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  		newMin = newMax = center; +		llassert(less_than_max_mag(center)); +		  		for (U32 i = 0; i < 4; i++)  		{  			LLVector4a delta; @@ -772,6 +806,9 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  			newMin.setMin(newMin,min);  			newMax.setMax(newMax,max); + +			llassert(less_than_max_mag(newMin)); +			llassert(less_than_max_mag(newMax));  		}  		if (!mDrawablep->isActive()) @@ -780,14 +817,22 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  			offset.load3(mDrawablep->getRegion()->getOriginAgent().mV);  			newMin.add(offset);  			newMax.add(offset); +			 +			llassert(less_than_max_mag(newMin)); +			llassert(less_than_max_mag(newMax));  		}  		t.setAdd(newMin, newMax);  		t.mul(0.5f); +		llassert(less_than_max_mag(t)); +		  		//VECTORIZE THIS  		mCenterLocal.set(t.getF32ptr()); +		llassert(less_than_max_mag(newMin)); +		llassert(less_than_max_mag(newMax)); +  		t.setSub(newMax,newMin);  		mBoundingSphereRadius = t.getLength3().getF32()*0.5f; @@ -1078,27 +1123,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	const LLTextureEntry *tep = mVObjp->getTE(f);  	const U8 bump_code = tep ? tep->getBumpmap() : 0; -	if (rebuild_pos) -	{ -		mVertexBuffer->getVertexStrider(vert, mGeomIndex); -		vertices = (LLVector4a*) vert.get(); -	} -	if (rebuild_normal) -	{ -		mVertexBuffer->getNormalStrider(norm, mGeomIndex); -		normals = (LLVector4a*) norm.get(); -	} -	if (rebuild_binormal) -	{ -		mVertexBuffer->getBinormalStrider(binorm, mGeomIndex); -		binormals = (LLVector4a*) binorm.get(); -	} -	if (rebuild_weights) -	{ -		mVertexBuffer->getWeight4Strider(wght, mGeomIndex); -		weights = (LLVector4a*) wght.get(); -	} -	  	F32 tcoord_xoffset = 0.f ;  	F32 tcoord_yoffset = 0.f ;  	F32 tcoord_xscale = 1.f ; @@ -1107,12 +1131,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	if (rebuild_tcoord)  	{ -		mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex); -		if (bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)) -		{ -			mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex); -		} -  		in_atlas = isAtlasInUse() ;  		if(in_atlas)  		{ @@ -1125,11 +1143,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			tcoord_yscale = tmp->mV[1] ;	  		}  	} -	if (rebuild_color) -	{	 -		mVertexBuffer->getColorStrider(colors, mGeomIndex); -	} - +	  	BOOL is_static = mDrawablep->isStatic();  	BOOL is_global = is_static; @@ -1168,7 +1182,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	// INDICES  	if (full_rebuild)  	{ -		mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex); +		mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount, true); +  		__m128i* dst = (__m128i*) indicesp.get();  		__m128i* src = (__m128i*) vf.mIndices;  		__m128i offset = _mm_set1_epi16(index_offset); @@ -1185,6 +1200,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		{  			indicesp[i] = vf.mIndices[i]+index_offset;  		} + +		mVertexBuffer->setBuffer(0);  	}  	LLMatrix4a mat_normal; @@ -1330,6 +1347,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		if (!in_atlas && !do_bump)  		{ //not in atlas or not bump mapped, might be able to do a cheap update +			mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount); +  			if (texgen != LLTextureEntry::TEX_GEN_PLANAR)  			{  				if (!do_tex_mat) @@ -1402,9 +1421,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  					}  				}  			} + +			mVertexBuffer->setBuffer(0);  		}  		else  		{ //either bump mapped or in atlas, just do the whole expensive loop +			mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, true); + +			std::vector<LLVector2> bump_tc; +		  			for (S32 i = 0; i < num_vertices; i++)  			{	  				LLVector2 tc(vf.mTexCoords[i]); @@ -1535,8 +1560,20 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  				*tex_coords++ = tc; -				 -				if (bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)) +				if (do_bump) +				{ +					bump_tc.push_back(tc); +				} +			} + +			mVertexBuffer->setBuffer(0); + + +			if (do_bump) +			{ +				mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, true); +		 +				for (S32 i = 0; i < num_vertices; i++)  				{  					LLVector4a tangent;  					tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]); @@ -1558,16 +1595,22 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  					}  					binormal.normalize3fast(); +					LLVector2 tc = bump_tc[i];  					tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() );  					*tex_coords2++ = tc; -				}	 +				} + +				mVertexBuffer->setBuffer(0);  			}  		}  	}  	if (rebuild_pos)  	{ +		mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, true); +		vertices = (LLVector4a*) vert.get(); +	  		LLMatrix4a mat_vert;  		mat_vert.loadu(mat_vert_in); @@ -1580,10 +1623,28 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			mat_vert.affineTransform(*src++, *dst++);  		}  		while(dst < end); + +		F32 index = (F32) (mTextureIndex < 255 ? mTextureIndex : 0); +		F32 *index_dst = (F32*) vertices; +		F32 *index_end = (F32*) end; + +		index_dst += 3; +		index_end += 3; +		do +		{ +			*index_dst = index; +			index_dst += 4; +		} +		while (index_dst < index_end); + +		mVertexBuffer->setBuffer(0);  	}  	if (rebuild_normal)  	{ +		mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, true); +		normals = (LLVector4a*) norm.get(); +	  		for (S32 i = 0; i < num_vertices; i++)  		{	  			LLVector4a normal; @@ -1591,10 +1652,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			normal.normalize3fast();  			normals[i] = normal;  		} + +		mVertexBuffer->setBuffer(0);  	}  	if (rebuild_binormal)  	{ +		mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, true); +		binormals = (LLVector4a*) binorm.get(); +		  		for (S32 i = 0; i < num_vertices; i++)  		{	  			LLVector4a binormal; @@ -1602,15 +1668,22 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			binormal.normalize3fast();  			binormals[i] = binormal;  		} + +		mVertexBuffer->setBuffer(0);  	}  	if (rebuild_weights && vf.mWeights)  	{ +		mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, true); +		weights = (LLVector4a*) wght.get();  		LLVector4a::memcpyNonAliased16((F32*) weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32)); +		mVertexBuffer->setBuffer(0);  	}  	if (rebuild_color)  	{ +		mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, true); +  		LLVector4a src;  		U32 vec[4]; @@ -1629,6 +1702,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		{	  			dst[i] = src;  		} + +		mVertexBuffer->setBuffer(0);  	}  	if (rebuild_tcoord) @@ -2045,13 +2120,13 @@ S32 LLFace::getColors(LLStrider<LLColor4U> &colors)  	}  	// llassert(mGeomIndex >= 0); -	mVertexBuffer->getColorStrider(colors, mGeomIndex); +	mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount);  	return mGeomIndex;  }  S32	LLFace::getIndices(LLStrider<U16> &indicesp)  { -	mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex); +	mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount);  	llassert(indicesp[0] != indicesp[1]);  	return mIndicesIndex;  } diff --git a/indra/newview/llface.h b/indra/newview/llface.h index b2170c4cf3..b5eaeecd60 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -94,6 +94,8 @@ public:  	U16				getGeomCount()		const	{ return mGeomCount; }		// vertex count for this face  	U16				getGeomIndex()		const	{ return mGeomIndex; }		// index into draw pool  	U16				getGeomStart()		const	{ return mGeomIndex; }		// index into draw pool +	void			setTextureIndex(U8 index); +	U8				getTextureIndex() const		{ return mTextureIndex; }  	void			setTexture(LLViewerTexture* tex) ;  	void            switchTexture(LLViewerTexture* new_texture);  	void            dirtyTexture(); @@ -262,6 +264,7 @@ private:  	U16			mGeomCount;			// vertex count for this face  	U16			mGeomIndex;			// index into draw pool +	U8			mTextureIndex;		// index of texture channel to use for pseudo-atlasing  	U32			mIndicesCount;  	U32			mIndicesIndex;		// index into draw pool for indices (yeah, I know!)  	S32         mIndexInTex ; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 9dd5269a6b..ab6753b4be 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -178,6 +178,80 @@ std::string lod_label_name[NUM_LOD+1] =  	"I went off the end of the lod_label_name array.  Me so smart."  }; + +#define LL_DEGENERACY_TOLERANCE  1e-7f + +inline F32 dot3fpu(const LLVector4a& a, const LLVector4a& b) +{ +    volatile F32 p0 = a[0] * b[0]; +    volatile F32 p1 = a[1] * b[1]; +    volatile F32 p2 = a[2] * b[2]; +    return p0 + p1 + p2; +} + +bool ll_is_degenerate(const LLVector4a& a, const LLVector4a& b, const LLVector4a& c, F32 tolerance = LL_DEGENERACY_TOLERANCE) +{ +        // small area check +        { +                LLVector4a edge1; edge1.setSub( a, b ); +                LLVector4a edge2; edge2.setSub( a, c ); +                ////////////////////////////////////////////////////////////////////////// +                /// Linden Modified +                ////////////////////////////////////////////////////////////////////////// + +                // If no one edge is more than 10x longer than any other edge, we weaken +                // the tolerance by a factor of 1e-4f. + +                LLVector4a edge3; edge3.setSub( c, b ); +				const F32 len1sq = edge1.dot3(edge1).getF32(); +                const F32 len2sq = edge2.dot3(edge2).getF32(); +                const F32 len3sq = edge3.dot3(edge3).getF32(); +                bool abOK = (len1sq <= 100.f * len2sq) && (len1sq <= 100.f * len3sq); +                bool acOK = (len2sq <= 100.f * len1sq) && (len1sq <= 100.f * len3sq); +                bool cbOK = (len3sq <= 100.f * len1sq) && (len1sq <= 100.f * len2sq); +                if ( abOK && acOK && cbOK ) +                { +                        tolerance *= 1e-4f; +                } + +                ////////////////////////////////////////////////////////////////////////// +                /// End Modified +                ////////////////////////////////////////////////////////////////////////// + +                LLVector4a cross; cross.setCross3( edge1, edge2 ); + +                LLVector4a edge1b; edge1b.setSub( b, a ); +                LLVector4a edge2b; edge2b.setSub( b, c ); +                LLVector4a crossb; crossb.setCross3( edge1b, edge2b ); + +                if ( ( cross.dot3(cross).getF32() < tolerance ) || ( crossb.dot3(crossb).getF32() < tolerance )) +                { +                        return true; +                } +        } + +        // point triangle distance check +        { +                LLVector4a Q; Q.setSub(a, b); +                LLVector4a R; R.setSub(c, b); + +                const F32 QQ = dot3fpu(Q, Q); +                const F32 RR = dot3fpu(R, R); +                const F32 QR = dot3fpu(R, Q); + +                volatile F32 QQRR = QQ * RR; +                volatile F32 QRQR = QR * QR; +                F32 Det = (QQRR - QRQR); + +                if( Det == 0.0f ) +                { +                        return true; +                } +        } + +        return false; +} +  bool validate_face(const LLVolumeFace& face)  {  	for (U32 i = 0; i < face.mNumIndices; ++i) @@ -189,6 +263,31 @@ bool validate_face(const LLVolumeFace& face)  		}  	} +	if (face.mNumIndices % 3 != 0 || face.mNumIndices == 0) +	{ +		llwarns << "Face has invalid number of indices." << llendl; +		return false; +	} + +	/*const LLVector4a scale(0.5f); + +	for (U32 i = 0; i < face.mNumIndices; i+=3) +	{ +		U16 idx1 = face.mIndices[i]; +		U16 idx2 = face.mIndices[i+1]; +		U16 idx3 = face.mIndices[i+2]; + +		LLVector4a v1; v1.setMul(face.mPositions[idx1], scale); +		LLVector4a v2; v2.setMul(face.mPositions[idx2], scale); +		LLVector4a v3; v3.setMul(face.mPositions[idx3], scale); + +		if (ll_is_degenerate(v1,v2,v3)) +		{ +			llwarns << "Degenerate face found!" << llendl; +			return false; +		} +	}*/ +  	return true;  } @@ -314,15 +413,17 @@ BOOL LLFloaterModelPreview::postBuild()  	childSetCommitCallback("pelvis_offset", onPelvisOffsetCommit, this);  	childSetCommitCallback("lod_file_or_limit", refresh, this); -	childSetCommitCallback("physics_load_radio", refresh, this); +	childSetCommitCallback("physics_load_radio", onPhysicsLoadRadioCommit, this);  	//childSetCommitCallback("physics_optimize", refresh, this);  	//childSetCommitCallback("physics_use_hull", refresh, this);  	childDisable("upload_skin");  	childDisable("upload_joints"); - +	  	childDisable("ok_btn"); +	childSetCommitCallback("confirm_checkbox", refresh, this); +  	mViewOptionMenuButton = getChild<LLMenuButton>("options_gear_btn");  	mCommitCallbackRegistrar.add("ModelImport.ViewOption.Action", boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _2)); @@ -470,6 +571,29 @@ void LLFloaterModelPreview::onPelvisOffsetCommit( LLUICtrl*, void* userdata )  }  //static +void LLFloaterModelPreview::onPhysicsLoadRadioCommit( LLUICtrl*, void *userdata) +{ +	LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance; +	if (fmp) +	{ +		if (fmp->childGetValue("physics_use_lod").asBoolean()) +		{ +			onPhysicsUseLOD(NULL,NULL); +		} +		if (fmp->childGetValue("physics_load_from_file").asBoolean()) +		{ +			 +		} +		LLModelPreview *model_preview = fmp->mModelPreview; +		if (model_preview) +		{ +			model_preview->refresh(); +			model_preview->updateStatusMessages(); +		} +	} +} + +//static  void LLFloaterModelPreview::onUploadJointsCommit(LLUICtrl*,void* userdata)  {  	LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata; @@ -573,6 +697,11 @@ void LLFloaterModelPreview::draw()  			childSetTextArg("status", "[STATUS]", getString(LLModel::getStatusString(mModelPreview->getLoadState() - LLModelLoader::ERROR_PARSING)));  		}  		else +		if ( mModelPreview->getLoadState() == LLModelLoader::ERROR_PARSING ) +		{ +			childSetTextArg("status", "[STATUS]", getString("status_parse_error")); +		} +		else  		{  			childSetTextArg("status", "[STATUS]", getString("status_idle"));  		} @@ -992,7 +1121,7 @@ LLModelLoader::LLModelLoader( std::string filename, S32 lod, LLModelPreview* pre  							  std::deque<std::string>& jointsFromNodes )  : mJointList( jointMap )  , mJointsFromNode( jointsFromNodes ) -, LLThread("Model Loader"), mFilename(filename), mLod(lod), mPreview(preview), mFirstTransform(TRUE) +, LLThread("Model Loader"), mFilename(filename), mLod(lod), mPreview(preview), mFirstTransform(TRUE), mNumOfFetchingTextures(0)  {  	mJointMap["mPelvis"] = "mPelvis";  	mJointMap["mTorso"] = "mTorso"; @@ -1157,11 +1286,7 @@ void stretch_extents(LLModel* model, LLMatrix4& mat, LLVector3& min, LLVector3&  void LLModelLoader::run()  { -	if (!doLoadModel()) -	{ -		mPreview = NULL; -	} - +	doLoadModel();  	doOnIdleOneTime(boost::bind(&LLModelLoader::loadModelCallback,this));  } @@ -1225,6 +1350,23 @@ bool LLModelLoader::doLoadModel()  		return false;  	} +	//Verify some basic properties of the dae +	//1. Basic validity check on controller  +	U32 controllerCount = (int) db->getElementCount( NULL, "controller" ); +	bool result = false; +	for ( int i=0; i<controllerCount; ++i ) +	{ +		domController* pController = NULL; +		db->getElement( (daeElement**) &pController, i , NULL, "controller" ); +		result = mPreview->verifyController( pController ); +		if (!result) +		{ +			setLoadState( ERROR_PARSING ); +			return true; +		} +	} + +  	//get unit scale  	mTransform.setIdentity(); @@ -1275,7 +1417,7 @@ bool LLModelLoader::doLoadModel()  			if(model->getStatus() != LLModel::NO_ERRORS)  			{  				setLoadState(ERROR_PARSING + model->getStatus()) ; -				return true ; //abort +				return false; //abort  			}  			if (model.notNull() && validate_model(model)) @@ -1634,7 +1776,7 @@ bool LLModelLoader::doLoadModel()  											{  												if (pos.getCount() <= j+2)  												{ -													llerrs << "WTF?" << llendl; +													llerrs << "Invalid position array size." << llendl;  												}  												LLVector3 v(pos[j], pos[j+1], pos[j+2]); @@ -1759,11 +1901,19 @@ bool LLModelLoader::doLoadModel()  	{  		llwarns << "document has no visual_scene" << llendl;  		setLoadState( ERROR_PARSING ); -		return false; +		return true;  	} +	  	setLoadState( DONE ); -	processElement(scene); +	bool badElement = false; +	 +	processElement( scene, badElement ); +	 +	if ( badElement ) +	{ +		setLoadState( ERROR_PARSING ); +	}  	return true;  } @@ -2124,7 +2274,8 @@ void LLModelLoader::loadTextures()  					iter->second[i].mMaterial[j].mDiffuseMap =   						LLViewerTextureManager::getFetchedTextureFromUrl("file://" + iter->second[i].mMaterial[j].mDiffuseMapFilename, TRUE, LLViewerTexture::BOOST_PREVIEW);  					iter->second[i].mMaterial[j].mDiffuseMap->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, mPreview, NULL, FALSE); -					iter->second[i].mMaterial[j].mDiffuseMap->forceToSaveRawImage(); +					iter->second[i].mMaterial[j].mDiffuseMap->forceToSaveRawImage(0, F32_MAX); +					mNumOfFetchingTextures++ ;  				}  			}  		} @@ -2153,6 +2304,90 @@ bool LLModelLoader::isNodeAJoint( domNode* pNode )  	return false;  } +//----------------------------------------------------------------------------- +// verifyCount +//----------------------------------------------------------------------------- +bool LLModelPreview::verifyCount( int expected, int result ) +{ +	if ( expected != result ) +	{ +		llinfos<< "Error: (expected/got)"<<expected<<"/"<<result<<"verts"<<llendl; +		return false; +	} +	return true; +} +//----------------------------------------------------------------------------- +// verifyController +//----------------------------------------------------------------------------- +bool LLModelPreview::verifyController( domController* pController ) +{	 + +	bool result = true; + +	domSkin* pSkin = pController->getSkin(); + +	if ( pSkin ) +	{ +		xsAnyURI & uri = pSkin->getSource(); +		domElement* pElement = uri.getElement(); + +		if ( !pElement ) +		{ +			llinfos<<"Can't resolve skin source"<<llendl; +			return false; +		} + +		daeString type_str = pElement->getTypeName(); +		if ( stricmp(type_str, "geometry") == 0 ) +		{	 +			//Skin is reference directly by geometry and get the vertex count from skin +			domSkin::domVertex_weights* pVertexWeights = pSkin->getVertex_weights(); +			U32 vertexWeightsCount = pVertexWeights->getCount(); +			domGeometry* pGeometry = (domGeometry*) (domElement*) uri.getElement(); +			domMesh* pMesh = pGeometry->getMesh();				 +			 +			if ( pMesh ) +			{ +				//Get vertex count from geometry +				domVertices* pVertices = pMesh->getVertices(); +				if ( !pVertices ) +				{  +					llinfos<<"No vertices!"<<llendl; +					return false; +				} + +				if ( pVertices ) +				{ +					xsAnyURI src = pVertices->getInput_array()[0]->getSource(); +					domSource* pSource = (domSource*) (domElement*) src.getElement(); +					U32 verticesCount = pSource->getTechnique_common()->getAccessor()->getCount(); +					result = verifyCount( verticesCount, vertexWeightsCount ); +					if ( !result ) +					{ +						return result; +					} +				} +			}	 + +			U32 vcountCount = (U32) pVertexWeights->getVcount()->getValue().getCount(); +			result = verifyCount( vcountCount, vertexWeightsCount );	 +			if ( !result ) +			{ +				return result; +			} + +			domInputLocalOffset_Array& inputs = pVertexWeights->getInput_array(); +			U32 sum = 0; +			for (size_t i=0; i<vcountCount; i++) +			{ +				sum += pVertexWeights->getVcount()->getValue()[i]; +			} +			result = verifyCount( sum * inputs.getCount(), (domInt) pVertexWeights->getV()->getValue().getCount() ); +		} +	} +	 +	return result; +}  //-----------------------------------------------------------------------------  // extractTranslation() @@ -2263,7 +2498,7 @@ daeElement* LLModelLoader::getChildFromElement( daeElement* pElement, std::strin      return NULL;  } -void LLModelLoader::processElement(daeElement* element) +void LLModelLoader::processElement( daeElement* element, bool& badElement )  {  	LLMatrix4 saved_transform = mTransform; @@ -2296,8 +2531,11 @@ void LLModelLoader::processElement(daeElement* element)  	{  		domFloat3 dom_value = scale->getValue(); + +		LLVector3 scale_vector = LLVector3(dom_value[0], dom_value[1], dom_value[2]); +		scale_vector.abs(); // Set all values positive, since we don't currently support mirrored meshes  		LLMatrix4 scaling; -		scaling.initScale(LLVector3(dom_value[0], dom_value[1], dom_value[2])); +		scaling.initScale(scale_vector);  		scaling *= mTransform;  		mTransform = scaling; @@ -2360,6 +2598,12 @@ void LLModelLoader::processElement(daeElement* element)  				}  			}  		} +		else  +		{ +			llinfos<<"Unable to resolve geometry URL."<<llendl; +			badElement = true;			 +		} +  	}  	domInstance_node* instance_node = daeSafeCast<domInstance_node>(element); @@ -2368,7 +2612,7 @@ void LLModelLoader::processElement(daeElement* element)  		daeElement* instance = instance_node->getUrl().getElement();  		if (instance)  		{ -			processElement(instance); +			processElement(instance,badElement);  		}  	} @@ -2376,7 +2620,7 @@ void LLModelLoader::processElement(daeElement* element)  	daeTArray< daeSmartRef<daeElement> > children = element->getChildren();  	for (S32 i = 0; i < children.getCount(); i++)  	{ -		processElement(children[i]); +		processElement(children[i],badElement);  	}  	domNode* node = daeSafeCast<domNode>(element); @@ -2660,7 +2904,7 @@ LLModelPreview::~LLModelPreview()  {  	if (mModelLoader)  	{ -		delete mModelLoader; +		mModelLoader->mPreview = NULL;  		mModelLoader = NULL;  	}  	//*HACK : *TODO : turn this back on when we understand why this crashes @@ -2675,7 +2919,8 @@ U32 LLModelPreview::calcResourceCost()  	if (mFMP && mModelLoader)  	{ -		if ( getLoadState() < LLModelLoader::ERROR_PARSING ) +		const BOOL confirmed_checkbox = mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->getValue().asBoolean(); +		if ( getLoadState() < LLModelLoader::ERROR_PARSING && confirmed_checkbox )  		{  			mFMP->childEnable("ok_btn");  		} @@ -2817,7 +3062,8 @@ void LLModelPreview::rebuildUploadData()  	F32 max_scale = 0.f; -	if ( mBaseScene.size() > 0 ) +	const BOOL confirmed_checkbox = mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->getValue().asBoolean(); +	if ( mBaseScene.size() > 0 && confirmed_checkbox )  	{  		mFMP->childEnable("ok_btn");  	} @@ -3221,6 +3467,8 @@ void LLModelPreview::loadModelCallback(S32 lod)  	}  	mLoading = false; +	if (mFMP) +		mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->set(FALSE);  	refresh();  	mModelLoadedSignal(); @@ -3234,7 +3482,7 @@ void LLModelPreview::resetPreviewTarget()  		mPreviewScale = (mModelLoader->mExtents[1] - mModelLoader->mExtents[0]) * 0.5f;  	} -	setPreviewTarget(mPreviewScale.magVec()*2.f); +	setPreviewTarget(mPreviewScale.magVec()*10.f);  }  void LLModelPreview::generateNormals() @@ -3752,7 +4000,35 @@ void LLModelPreview::updateStatusMessages()  		mMaxTriangleLimit = total_tris[LLModel::LOD_HIGH];  	} +	bool has_degenerate = false; + +	{//check for degenerate triangles in physics mesh +		U32 lod = LLModel::LOD_PHYSICS; +		const LLVector4a scale(0.5f); +		for (U32 i = 0; i < mModel[lod].size() && !has_degenerate; ++i) +		{ //for each model in the lod +			if (mModel[lod][i]->mPhysics.mHull.empty()) +			{ //no decomp exists +				S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces(); +				for (S32 j = 0; j < cur_submeshes && !has_degenerate; ++j) +				{ //for each submesh (face), add triangles and vertices to current total +					const LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j); +					for (S32 k = 0; k < face.mNumIndices && !has_degenerate; ) +					{ +						LLVector4a v1; v1.setMul(face.mPositions[face.mIndices[k++]], scale); +						LLVector4a v2; v2.setMul(face.mPositions[face.mIndices[k++]], scale); +						LLVector4a v3; v3.setMul(face.mPositions[face.mIndices[k++]], scale); +						if (ll_is_degenerate(v1,v2,v3)) +						{ +							has_degenerate = true; +						} +					} +				} +			} +		} +	} +	  	mFMP->childSetTextArg("submeshes_info", "[SUBMESHES]", llformat("%d", total_submeshes[LLModel::LOD_HIGH]));  	std::string mesh_status_na = mFMP->getString("mesh_status_na"); @@ -3853,7 +4129,10 @@ void LLModelPreview::updateStatusMessages()  		for (U32 j = 0; upload_ok && j < mdl->mPhysics.mHull.size(); ++j)  		{ -			upload_ok = upload_ok && mdl->mPhysics.mHull[i].size() <= 256; +			if (mdl->mPhysics.mHull[j].size() > 256) +			{ +				upload_ok = false; +			}  		}  	} @@ -3876,7 +4155,16 @@ void LLModelPreview::updateStatusMessages()  		}  	} -	if ( upload_ok && !errorStateFromLoader && skinAndRigOk ) +	if(upload_ok && mModelLoader) +	{ +		if(!mModelLoader->areTexturesReady() && mFMP->childGetValue("upload_textures").asBoolean()) +		{ +			upload_ok = false ; +		} +	} + +	const BOOL confirmed_checkbox = mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->getValue().asBoolean(); +	if ( upload_ok && !errorStateFromLoader && skinAndRigOk && !has_degenerate && confirmed_checkbox)  	{  		mFMP->childEnable("ok_btn");  	} @@ -4238,11 +4526,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)  					const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos);  					LLVector4 w(0,0,0,0); -					if (weight_list.size() > 4) -					{ -						llerrs << "WTF?" << llendl; -					} - +					  					for (U32 i = 0; i < weight_list.size(); ++i)  					{  						F32 wght = llmin(weight_list[i].mWeight, 0.999999f); @@ -4455,7 +4739,7 @@ BOOL LLModelPreview::render()  	LLVector3 target_pos = mPreviewTarget+offset;  	F32 z_near = 0.001f; -	F32 z_far = mCameraDistance+mPreviewScale.magVec()+mCameraOffset.magVec(); +	F32 z_far = mCameraDistance*10.0f+mPreviewScale.magVec()+mCameraOffset.magVec();  	if (skin_weight)  	{ @@ -4605,39 +4889,43 @@ BOOL LLModelPreview::render()  						LLModel::Decomposition& physics = model->mPhysics; -						if (physics.mMesh.empty()) -						{ //build vertex buffer for physics mesh -							gMeshRepo.buildPhysicsMesh(physics); -						} -							 -						if (!physics.mMesh.empty()) -						{ //render hull instead of mesh +						if (!physics.mHull.empty()) +						{  							render_mesh = false; -							for (U32 i = 0; i < physics.mMesh.size(); ++i) -							{ -								if (explode > 0.f) + +							if (physics.mMesh.empty()) +							{ //build vertex buffer for physics mesh +								gMeshRepo.buildPhysicsMesh(physics); +							} +						 +							if (!physics.mMesh.empty()) +							{ //render hull instead of mesh +								for (U32 i = 0; i < physics.mMesh.size(); ++i)  								{ -									gGL.pushMatrix(); +									if (explode > 0.f) +									{ +										gGL.pushMatrix(); -									LLVector3 offset = model->mHullCenter[i]-model->mCenterOfHullCenters; -									offset *= explode; +										LLVector3 offset = model->mHullCenter[i]-model->mCenterOfHullCenters; +										offset *= explode; -									gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]); -								} +										gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]); +									} -								static std::vector<LLColor4U> hull_colors; +									static std::vector<LLColor4U> hull_colors; -								if (i+1 >= hull_colors.size()) -								{ -									hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 255)); -								} +									if (i+1 >= hull_colors.size()) +									{ +										hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 255)); +									} -									glColor4ubv(hull_colors[i].mV); -								LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals); +										glColor4ubv(hull_colors[i].mV); +									LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals); -								if (explode > 0.f) -								{ -									gGL.popMatrix(); +									if (explode > 0.f) +									{ +										gGL.popMatrix(); +									}  								}  							}  						} @@ -4663,9 +4951,10 @@ BOOL LLModelPreview::render()  							glColor3f(1.f, 1.f, 0.f); -							glLineWidth(3.f); +							glLineWidth(2.f);  							glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);  							buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0); +  							glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);  							glLineWidth(1.f);  						} @@ -4674,6 +4963,80 @@ BOOL LLModelPreview::render()  					gGL.popMatrix();  				} +				glLineWidth(3.f); +				glPointSize(8.f); +				gPipeline.enableLightsFullbright(LLColor4::white); +				//show degenerate triangles +				LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); +				LLGLDisable cull(GL_CULL_FACE); +				glColor4f(1.f,0.f,0.f,1.f); +				const LLVector4a scale(0.5f); + +				for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) +				{ +					LLModelInstance& instance = *iter; + +					LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS]; + +					if (!model) +					{ +						continue; +					} + +					gGL.pushMatrix(); +					LLMatrix4 mat = instance.mTransform; + +					glMultMatrixf((GLfloat*) mat.mMatrix); + + +					LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread; +					if (decomp) +					{ +						LLMutexLock(decomp->mMutex); + +						LLModel::Decomposition& physics = model->mPhysics; + +						if (physics.mHull.empty()) +						{ +							if (mVertexBuffer[LLModel::LOD_PHYSICS].empty()) +							{ +								genBuffers(LLModel::LOD_PHYSICS, false); +							} +							 +							for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i) +							{ +								LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i]; + +								buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); + +								LLStrider<LLVector3> pos_strider;  +								buffer->getVertexStrider(pos_strider, 0); +								LLVector4a* pos = (LLVector4a*) pos_strider.get(); +							 +								LLStrider<U16> idx; +								buffer->getIndexStrider(idx, 0); + +								for (U32 i = 0; i < buffer->getNumIndices(); i += 3) +								{ +									LLVector4a v1; v1.setMul(pos[*idx++], scale); +									LLVector4a v2; v2.setMul(pos[*idx++], scale); +									LLVector4a v3; v3.setMul(pos[*idx++], scale); + +									if (ll_is_degenerate(v1,v2,v3)) +									{ +										buffer->draw(LLRender::LINE_LOOP, 3, i); +										buffer->draw(LLRender::POINTS, 3, i); +									} +								} +							} +						} +					} + +					gGL.popMatrix(); +				} +				glLineWidth(1.f); +				glPointSize(1.f); +				gPipeline.enableLightsPreview();  				gGL.setSceneBlendType(LLRender::BT_ALPHA);  			}  		} @@ -4938,6 +5301,14 @@ void LLModelPreview::textureLoadedCallback( BOOL success, LLViewerFetchedTexture  {  	LLModelPreview* preview = (LLModelPreview*) userdata;  	preview->refresh(); + +	if(final && preview->mModelLoader) +	{ +		if(preview->mModelLoader->mNumOfFetchingTextures > 0) +		{ +			preview->mModelLoader->mNumOfFetchingTextures-- ; +		} +	}  }  void LLModelPreview::onLODParamCommit(bool enforce_tri_limit) @@ -4959,35 +5330,7 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL  	mParams = sInstance->mDecompParams;  	//copy out positions and indices -	if (mdl) -	{ -		U16 index_offset = 0; - -		mPositions.clear(); -		mIndices.clear(); - -		//queue up vertex positions and indices -		for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) -		{ -			const LLVolumeFace& face = mdl->getVolumeFace(i); -			if (mPositions.size() + face.mNumVertices > 65535) -			{ -				continue; -			} - -			for (U32 j = 0; j < face.mNumVertices; ++j) -			{ -				mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr())); -			} - -			for (U32 j = 0; j < face.mNumIndices; ++j) -			{ -				mIndices.push_back(face.mIndices[j]+index_offset); -			} - -			index_offset += face.mNumVertices; -		} -	} +	assignData(mdl) ;	  }  void LLFloaterModelPreview::setStatusMessage(const std::string& msg) diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index f6d4a08d1f..ccd6fef953 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -1,431 +1,441 @@ -/** - * @file llfloatermodelpreview.h - * @brief LLFloaterModelPreview class definition - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLFLOATERMODELPREVIEW_H -#define LL_LLFLOATERMODELPREVIEW_H - -#include "llfloaternamedesc.h" - -#include "lldynamictexture.h" -#include "llfloatermodelwizard.h" -#include "llquaternion.h" -#include "llmeshrepository.h" -#include "llmodel.h" -#include "llthread.h" -#include "llviewermenufile.h" - -class LLComboBox; -class LLJoint; -class LLViewerJointMesh; -class LLVOAvatar; -class LLTextBox; -class LLVertexBuffer; -class LLModelPreview; -class LLFloaterModelPreview; -class daeElement; -class domProfile_COMMON; -class domInstance_geometry; -class domNode; -class domTranslate; -class LLMenuButton; -class LLToggleableMenu; - -typedef std::map<std::string, LLMatrix4> JointTransformMap; -typedef std::map<std::string, LLMatrix4>:: iterator JointTransformMapIt; - -const S32 NUM_LOD = 4; - -class LLModelLoader : public LLThread -{ -public: -	typedef enum -	{ -		STARTING = 0, -		READING_FILE, -		CREATING_FACES, -		GENERATING_VERTEX_BUFFERS, -		GENERATING_LOD, -		DONE, -		ERROR_PARSING //basically loading failed -	} eLoadState; - -	U32 mState; -	std::string mFilename; -	S32 mLod; -	LLModelPreview* mPreview; -	LLMatrix4 mTransform; -	BOOL mFirstTransform; -	LLVector3 mExtents[2]; -	bool mTrySLM; -	 -	std::map<daeElement*, LLPointer<LLModel> > mModel; -	 -	typedef std::vector<LLPointer<LLModel> > model_list; -	model_list mModelList; - -	typedef std::vector<LLModelInstance> model_instance_list; -	 -	typedef std::map<LLMatrix4, model_instance_list > scene; - -	scene mScene; - -	typedef std::queue<LLPointer<LLModel> > model_queue; - -	//queue of models that need a physics rep -	model_queue mPhysicsQ; - -	LLModelLoader( std::string filename, S32 lod, LLModelPreview* preview, JointTransformMap& jointMap,  -				   std::deque<std::string>& jointsFromNodes ); -	~LLModelLoader() ; - -	virtual void run(); -	bool doLoadModel(); -	bool loadFromSLM(const std::string& filename); -	void loadModelCallback(); - -	void loadTextures() ; //called in the main thread. -	void processElement(daeElement* element); -	std::vector<LLImportMaterial> getMaterials(LLModel* model, domInstance_geometry* instance_geo); -	LLImportMaterial profileToMaterial(domProfile_COMMON* material); -	std::string getElementLabel(daeElement *element); -	LLColor4 getDaeColor(daeElement* element); -	 -	daeElement* getChildFromElement( daeElement* pElement, std::string const & name ); -	 -	bool isNodeAJoint( domNode* pNode ); -	void processJointNode( domNode* pNode, std::map<std::string,LLMatrix4>& jointTransforms ); -	void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform ); -	void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform ); -	 -	void setLoadState(U32 state); - -	void buildJointToNodeMappingFromScene( daeElement* pRoot ); -	void processJointToNodeMapping( domNode* pNode ); - - -	//map of avatar joints as named in COLLADA assets to internal joint names -	std::map<std::string, std::string> mJointMap; -	JointTransformMap& mJointList;	 -	std::deque<std::string>& mJointsFromNode; - -private: -	static std::list<LLModelLoader*> sActiveLoaderList; -	static bool isAlive(LLModelLoader* loader) ; -}; - -class LLFloaterModelPreview : public LLFloater -{ -public: -	 -	class DecompRequest : public LLPhysicsDecomp::Request -	{ -	public: -		S32 mContinue; -		LLPointer<LLModel> mModel; -		 -		DecompRequest(const std::string& stage, LLModel* mdl); -		virtual S32 statusCallback(const char* status, S32 p1, S32 p2); -		virtual void completed(); -		 -	}; -	static LLFloaterModelPreview* sInstance; -	 -	LLFloaterModelPreview(const LLSD& key); -	virtual ~LLFloaterModelPreview(); -	 -	virtual BOOL postBuild(); -	 -	BOOL handleMouseDown(S32 x, S32 y, MASK mask); -	BOOL handleMouseUp(S32 x, S32 y, MASK mask); -	BOOL handleHover(S32 x, S32 y, MASK mask); -	BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);  -	 -	static void onMouseCaptureLostModelPreview(LLMouseHandler*); -	static void setUploadAmount(S32 amount) { sUploadAmount = amount; } - -	void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost); -	 -	static void onBrowseLOD(void* data); -	 -	static void onReset(void* data); - -	static void onUpload(void* data); -	 -	static void onClearMaterials(void* data); -	 -	static void refresh(LLUICtrl* ctrl, void* data); -	 -	void updateResourceCost(); -	 -	void			loadModel(S32 lod); -	 -	void onViewOptionChecked(const LLSD& userdata); -	bool isViewOptionChecked(const LLSD& userdata); -	bool isViewOptionEnabled(const LLSD& userdata); -	void setViewOptionEnabled(const std::string& option, bool enabled); -	void enableViewOption(const std::string& option); -	void disableViewOption(const std::string& option); - -protected: -	friend class LLModelPreview; -	friend class LLMeshFilePicker; -	friend class LLPhysicsDecomp; -	 -	static void		onImportScaleCommit(LLUICtrl*, void*); -	static void		onPelvisOffsetCommit(LLUICtrl*, void*); -	static void		onUploadJointsCommit(LLUICtrl*,void*); -	static void		onUploadSkinCommit(LLUICtrl*,void*); -	 -	static void		onPreviewLODCommit(LLUICtrl*,void*); -	 -	static void		onGenerateNormalsCommit(LLUICtrl*,void*); -	 -	static void		onAutoFillCommit(LLUICtrl*,void*); -	static void		onLODParamCommit(LLUICtrl*,void*); -	static void		onLODParamCommitTriangleLimit(LLUICtrl*,void*); -	 -	static void		onExplodeCommit(LLUICtrl*, void*); -	 -	static void onPhysicsParamCommit(LLUICtrl* ctrl, void* userdata); -	static void onPhysicsStageExecute(LLUICtrl* ctrl, void* userdata); -	static void onCancel(LLUICtrl* ctrl, void* userdata); -	static void onPhysicsStageCancel(LLUICtrl* ctrl, void* userdata); -	 -	static void onPhysicsBrowse(LLUICtrl* ctrl, void* userdata); -	static void onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata); -	static void onPhysicsOptimize(LLUICtrl* ctrl, void* userdata); -	static void onPhysicsDecomposeBack(LLUICtrl* ctrl, void* userdata); -	static void onPhysicsSimplifyBack(LLUICtrl* ctrl, void* userdata); -		 -	void			draw(); -	 -	void initDecompControls(); -	 -	void setStatusMessage(const std::string& msg); - -	LLModelPreview*	mModelPreview; -	 -	LLPhysicsDecomp::decomp_params mDecompParams; -	 -	S32				mLastMouseX; -	S32				mLastMouseY; -	LLRect			mPreviewRect; -	U32				mGLName; -	static S32		sUploadAmount; -	 -	std::set<LLPointer<DecompRequest> > mCurRequest; -	std::string mStatusMessage; - -	//use "disabled" as false by default -	std::map<std::string, bool> mViewOptionDisabled; -	 -	//store which lod mode each LOD is using -	// 0 - load from file -	// 1 - auto generate -	// 2 - None -	S32 mLODMode[4]; - -	LLMenuButton* mViewOptionMenuButton; -	LLToggleableMenu* mViewOptionMenu; -	LLMutex* mStatusLock; - -}; - -class LLMeshFilePicker : public LLFilePickerThread -{ -public: -	LLMeshFilePicker(LLModelPreview* mp, S32 lod); -	virtual void notify(const std::string& filename); - -private: -	LLModelPreview* mMP; -	S32 mLOD; -}; - - -class LLModelPreview : public LLViewerDynamicTexture, public LLMutex -{	 -	typedef boost::signals2::signal<void (F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost)> details_signal_t; -	typedef boost::signals2::signal<void (void)> model_loaded_signal_t; - -public: -	LLModelPreview(S32 width, S32 height, LLFloater* fmp); -	virtual ~LLModelPreview(); - -	void resetPreviewTarget(); -	void setPreviewTarget(F32 distance); -	void setTexture(U32 name) { mTextureName = name; } - -	void setPhysicsFromLOD(S32 lod); -	BOOL render(); -	void update(); -	void genBuffers(S32 lod, bool skinned); -	void clearBuffers(); -	void refresh(); -	void rotate(F32 yaw_radians, F32 pitch_radians); -	void zoom(F32 zoom_amt); -	void pan(F32 right, F32 up); -	virtual BOOL needsRender() { return mNeedsUpdate; } -	void setPreviewLOD(S32 lod); -	void clearModel(S32 lod); -	void loadModel(std::string filename, S32 lod); -	void loadModelCallback(S32 lod); -	void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false); -	void generateNormals(); -	void clearMaterials(); -	U32 calcResourceCost(); -	void rebuildUploadData(); -	void saveUploadData(bool save_skinweights, bool save_joint_poisitions); -	void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_poisitions); -	void clearIncompatible(S32 lod); -	void updateStatusMessages(); -	void clearGLODGroup(); -	void onLODParamCommit(bool enforce_tri_limit); - -	const bool getModelPivot( void ) const { return mHasPivot; } -	void setHasPivot( bool val ) { mHasPivot = val; } -	void setModelPivot( const LLVector3& pivot ) { mModelPivot = pivot; } - -	//Sets the current avatars joints to new positions -	//Makes in world go to shit, however -	void changeAvatarsJointPositions( LLModel* pModel ); -	//Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps) -	void critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset ); -	void critiqueJointToNodeMappingFromScene( void  ); -	//Is a rig valid so that it can be used as a criteria for allowing for uploading of joint positions -	//Accessors for joint position upload friendly rigs -	const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; } -	void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; } -	bool isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset ); -	//Determines if a rig is a legacy from the joint list -	bool isRigLegacy( const std::vector<std::string> &jointListFromAsset );	 -	//Accessors for the legacy rigs -	const bool isLegacyRigValid( void ) const { return mLegacyRigValid; } -	void setLegacyRigValid( bool rigValid ) { mLegacyRigValid = rigValid; }	 - -	static void	textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); -	 -	boost::signals2::connection setDetailsCallback( const details_signal_t::slot_type& cb ){  return mDetailsSignal.connect(cb);  } -	boost::signals2::connection setModelLoadedCallback( const model_loaded_signal_t::slot_type& cb ){  return mModelLoadedSignal.connect(cb);  } -	 -	void setLoadState( U32 state ) { mLoadState = state; } -	U32 getLoadState() { return mLoadState; } -	//setRestJointFlag: If an asset comes through that changes the joints, we want the reset to persist -	void setResetJointFlag( bool state ) { if ( !mResetJoints ) mResetJoints = state; } -	const bool getResetJointFlag( void ) const { return mResetJoints; } -	void setRigWithSceneParity( bool state ) { mRigParityWithScene = state; } -	const bool getRigWithSceneParity( void ) const { return mRigParityWithScene; } -	 -	LLVector3 getTranslationForJointOffset( std::string joint ); - -	void		createPreviewAvatar( void ); -	LLVOAvatar* getPreviewAvatar( void ) { return mPreviewAvatar; } - - protected: -	friend class LLModelLoader; -	friend class LLFloaterModelPreview; -	friend class LLFloaterModelWizard; -	friend class LLFloaterModelPreview::DecompRequest; -	friend class LLFloaterModelWizard::DecompRequest; -	friend class LLPhysicsDecomp; - -	LLFloater*  mFMP; - -	BOOL        mNeedsUpdate; -	bool		mDirty; -	bool		mGenLOD; -	U32         mTextureName; -	F32			mCameraDistance; -	F32			mCameraYaw; -	F32			mCameraPitch; -	F32			mCameraZoom; -	LLVector3	mCameraOffset; -	LLVector3	mPreviewTarget; -	LLVector3	mPreviewScale; -	S32			mPreviewLOD; -	U32			mResourceCost; -	std::string mLODFile[LLModel::NUM_LODS]; -	bool		mLoading; -	U32			mLoadState; -	bool		mResetJoints; -	bool		mRigParityWithScene; -	 -	std::map<std::string, bool> mViewOption; - -	//GLOD object parameters (must rebuild object if these change) -	bool mLODFrozen; -	F32 mBuildShareTolerance; -	U32 mBuildQueueMode; -	U32 mBuildOperator; -	U32 mBuildBorderMode; -	U32 mRequestedLoDMode[LLModel::NUM_LODS]; -	S32 mRequestedTriangleCount[LLModel::NUM_LODS]; -	F32 mRequestedErrorThreshold[LLModel::NUM_LODS]; -	U32 mRequestedBuildOperator[LLModel::NUM_LODS]; -	U32 mRequestedQueueMode[LLModel::NUM_LODS]; -	U32 mRequestedBorderMode[LLModel::NUM_LODS]; -	F32 mRequestedShareTolerance[LLModel::NUM_LODS]; -	F32 mRequestedCreaseAngle[LLModel::NUM_LODS]; - -	LLModelLoader* mModelLoader; - -	LLModelLoader::scene mScene[LLModel::NUM_LODS]; -	LLModelLoader::scene mBaseScene; - -	LLModelLoader::model_list mModel[LLModel::NUM_LODS]; -	LLModelLoader::model_list mBaseModel; - -	U32 mGroup; -	std::map<LLPointer<LLModel>, U32> mObject; -	U32 mMaxTriangleLimit; -	 -	LLMeshUploadThread::instance_list mUploadData; -	std::set<LLViewerFetchedTexture* > mTextureSet; - -	//map of vertex buffers to models (one vertex buffer in vector per face in model -	std::map<LLModel*, std::vector<LLPointer<LLVertexBuffer> > > mVertexBuffer[LLModel::NUM_LODS+1]; - -	details_signal_t mDetailsSignal; -	model_loaded_signal_t mModelLoadedSignal; -	 -	LLVector3	mModelPivot; -	bool		mHasPivot; -	 -	float		mPelvisZOffset; -	 -	bool		mRigValidJointUpload; -	bool		mLegacyRigValid; - -	bool		mLastJointUpdate; - -	std::deque<std::string> mMasterJointList; -	std::deque<std::string> mMasterLegacyJointList; -	std::deque<std::string> mJointsFromNode; -	JointTransformMap		mJointTransformMap; -	LLPointer<LLVOAvatar>	mPreviewAvatar; -}; - -#endif  // LL_LLFLOATERMODELPREVIEW_H +/**
 + * @file llfloatermodelpreview.h
 + * @brief LLFloaterModelPreview class definition
 + *
 + * $LicenseInfo:firstyear=2004&license=viewerlgpl$
 + * Second Life Viewer Source Code
 + * Copyright (C) 2010, Linden Research, Inc.
 + * 
 + * This library is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation;
 + * version 2.1 of the License only.
 + * 
 + * This library is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + * 
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with this library; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 + * 
 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 + * $/LicenseInfo$
 + */
 +
 +#ifndef LL_LLFLOATERMODELPREVIEW_H
 +#define LL_LLFLOATERMODELPREVIEW_H
 +
 +#include "llfloaternamedesc.h"
 +
 +#include "lldynamictexture.h"
 +#include "llfloatermodelwizard.h"
 +#include "llquaternion.h"
 +#include "llmeshrepository.h"
 +#include "llmodel.h"
 +#include "llthread.h"
 +#include "llviewermenufile.h"
 +
 +class LLComboBox;
 +class LLJoint;
 +class LLViewerJointMesh;
 +class LLVOAvatar;
 +class LLTextBox;
 +class LLVertexBuffer;
 +class LLModelPreview;
 +class LLFloaterModelPreview;
 +class daeElement;
 +class domProfile_COMMON;
 +class domInstance_geometry;
 +class domNode;
 +class domTranslate;
 +class domController;
 +class LLMenuButton;
 +class LLToggleableMenu;
 +
 +typedef std::map<std::string, LLMatrix4> JointTransformMap;
 +typedef std::map<std::string, LLMatrix4>:: iterator JointTransformMapIt;
 +
 +const S32 NUM_LOD = 4;
 +
 +class LLModelLoader : public LLThread
 +{
 +public:
 +	typedef enum
 +	{
 +		STARTING = 0,
 +		READING_FILE,
 +		CREATING_FACES,
 +		GENERATING_VERTEX_BUFFERS,
 +		GENERATING_LOD,
 +		DONE,
 +		ERROR_PARSING //basically loading failed
 +	} eLoadState;
 +
 +	U32 mState;
 +	std::string mFilename;
 +	S32 mLod;
 +	LLModelPreview* mPreview;
 +	LLMatrix4 mTransform;
 +	BOOL mFirstTransform;
 +	LLVector3 mExtents[2];
 +	bool mTrySLM;
 +	
 +	std::map<daeElement*, LLPointer<LLModel> > mModel;
 +	
 +	typedef std::vector<LLPointer<LLModel> > model_list;
 +	model_list mModelList;
 +
 +	typedef std::vector<LLModelInstance> model_instance_list;
 +	
 +	typedef std::map<LLMatrix4, model_instance_list > scene;
 +
 +	scene mScene;
 +
 +	typedef std::queue<LLPointer<LLModel> > model_queue;
 +
 +	//queue of models that need a physics rep
 +	model_queue mPhysicsQ;
 +
 +	LLModelLoader( std::string filename, S32 lod, LLModelPreview* preview, JointTransformMap& jointMap, 
 +				   std::deque<std::string>& jointsFromNodes );
 +	~LLModelLoader() ;
 +
 +	virtual void run();
 +	bool doLoadModel();
 +	bool loadFromSLM(const std::string& filename);
 +	void loadModelCallback();
 +
 +	void loadTextures() ; //called in the main thread.
 +	void processElement(daeElement* element, bool& badElement);
 +	std::vector<LLImportMaterial> getMaterials(LLModel* model, domInstance_geometry* instance_geo);
 +	LLImportMaterial profileToMaterial(domProfile_COMMON* material);
 +	std::string getElementLabel(daeElement *element);
 +	LLColor4 getDaeColor(daeElement* element);
 +	
 +	daeElement* getChildFromElement( daeElement* pElement, std::string const & name );
 +	
 +	bool isNodeAJoint( domNode* pNode );
 +	void processJointNode( domNode* pNode, std::map<std::string,LLMatrix4>& jointTransforms );
 +	void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform );
 +	void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform );
 +	
 +	void setLoadState(U32 state);
 +
 +	void buildJointToNodeMappingFromScene( daeElement* pRoot );
 +	void processJointToNodeMapping( domNode* pNode );
 +
 +
 +	//map of avatar joints as named in COLLADA assets to internal joint names
 +	std::map<std::string, std::string> mJointMap;
 +	JointTransformMap& mJointList;	
 +	std::deque<std::string>& mJointsFromNode;
 +
 +	S32 mNumOfFetchingTextures ; //updated in the main thread
 +	bool areTexturesReady() { return !mNumOfFetchingTextures; } //called in the main thread.
 +
 +private:
 +	static std::list<LLModelLoader*> sActiveLoaderList;
 +	static bool isAlive(LLModelLoader* loader) ;
 +};
 +
 +class LLFloaterModelPreview : public LLFloater
 +{
 +public:
 +	
 +	class DecompRequest : public LLPhysicsDecomp::Request
 +	{
 +	public:
 +		S32 mContinue;
 +		LLPointer<LLModel> mModel;
 +		
 +		DecompRequest(const std::string& stage, LLModel* mdl);
 +		virtual S32 statusCallback(const char* status, S32 p1, S32 p2);
 +		virtual void completed();
 +		
 +	};
 +	static LLFloaterModelPreview* sInstance;
 +	
 +	LLFloaterModelPreview(const LLSD& key);
 +	virtual ~LLFloaterModelPreview();
 +	
 +	virtual BOOL postBuild();
 +	
 +	BOOL handleMouseDown(S32 x, S32 y, MASK mask);
 +	BOOL handleMouseUp(S32 x, S32 y, MASK mask);
 +	BOOL handleHover(S32 x, S32 y, MASK mask);
 +	BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); 
 +	
 +	static void onMouseCaptureLostModelPreview(LLMouseHandler*);
 +	static void setUploadAmount(S32 amount) { sUploadAmount = amount; }
 +
 +	void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost);
 +	
 +	static void onBrowseLOD(void* data);
 +	
 +	static void onReset(void* data);
 +
 +	static void onUpload(void* data);
 +	
 +	static void onClearMaterials(void* data);
 +	
 +	static void refresh(LLUICtrl* ctrl, void* data);
 +	
 +	void updateResourceCost();
 +	
 +	void			loadModel(S32 lod);
 +	
 +	void onViewOptionChecked(const LLSD& userdata);
 +	bool isViewOptionChecked(const LLSD& userdata);
 +	bool isViewOptionEnabled(const LLSD& userdata);
 +	void setViewOptionEnabled(const std::string& option, bool enabled);
 +	void enableViewOption(const std::string& option);
 +	void disableViewOption(const std::string& option);
 +
 +protected:
 +	friend class LLModelPreview;
 +	friend class LLMeshFilePicker;
 +	friend class LLPhysicsDecomp;
 +	
 +	static void		onImportScaleCommit(LLUICtrl*, void*);
 +	static void		onPelvisOffsetCommit(LLUICtrl*, void*);
 +	static void		onUploadJointsCommit(LLUICtrl*,void*);
 +	static void		onUploadSkinCommit(LLUICtrl*,void*);
 +	
 +	static void		onPhysicsLoadRadioCommit(LLUICtrl*,void *data);
 +
 +	static void		onPreviewLODCommit(LLUICtrl*,void*);
 +	
 +	static void		onGenerateNormalsCommit(LLUICtrl*,void*);
 +	
 +	static void		onAutoFillCommit(LLUICtrl*,void*);
 +	static void		onLODParamCommit(LLUICtrl*,void*);
 +	static void		onLODParamCommitTriangleLimit(LLUICtrl*,void*);
 +	
 +	static void		onExplodeCommit(LLUICtrl*, void*);
 +	
 +	static void onPhysicsParamCommit(LLUICtrl* ctrl, void* userdata);
 +	static void onPhysicsStageExecute(LLUICtrl* ctrl, void* userdata);
 +	static void onCancel(LLUICtrl* ctrl, void* userdata);
 +	static void onPhysicsStageCancel(LLUICtrl* ctrl, void* userdata);
 +	
 +	static void onPhysicsBrowse(LLUICtrl* ctrl, void* userdata);
 +	static void onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata);
 +	static void onPhysicsOptimize(LLUICtrl* ctrl, void* userdata);
 +	static void onPhysicsDecomposeBack(LLUICtrl* ctrl, void* userdata);
 +	static void onPhysicsSimplifyBack(LLUICtrl* ctrl, void* userdata);
 +		
 +	void			draw();
 +	
 +	void initDecompControls();
 +	
 +	void setStatusMessage(const std::string& msg);
 +
 +	LLModelPreview*	mModelPreview;
 +	
 +	LLPhysicsDecomp::decomp_params mDecompParams;
 +	
 +	S32				mLastMouseX;
 +	S32				mLastMouseY;
 +	LLRect			mPreviewRect;
 +	U32				mGLName;
 +	static S32		sUploadAmount;
 +	
 +	std::set<LLPointer<DecompRequest> > mCurRequest;
 +	std::string mStatusMessage;
 +
 +	//use "disabled" as false by default
 +	std::map<std::string, bool> mViewOptionDisabled;
 +	
 +	//store which lod mode each LOD is using
 +	// 0 - load from file
 +	// 1 - auto generate
 +	// 2 - None
 +	S32 mLODMode[4];
 +
 +	LLMenuButton* mViewOptionMenuButton;
 +	LLToggleableMenu* mViewOptionMenu;
 +	LLMutex* mStatusLock;
 +
 +};
 +
 +class LLMeshFilePicker : public LLFilePickerThread
 +{
 +public:
 +	LLMeshFilePicker(LLModelPreview* mp, S32 lod);
 +	virtual void notify(const std::string& filename);
 +
 +private:
 +	LLModelPreview* mMP;
 +	S32 mLOD;
 +};
 +
 +
 +class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
 +{	
 +	typedef boost::signals2::signal<void (F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost)> details_signal_t;
 +	typedef boost::signals2::signal<void (void)> model_loaded_signal_t;
 +
 +public:
 +	LLModelPreview(S32 width, S32 height, LLFloater* fmp);
 +	virtual ~LLModelPreview();
 +
 +	void resetPreviewTarget();
 +	void setPreviewTarget(F32 distance);
 +	void setTexture(U32 name) { mTextureName = name; }
 +
 +	void setPhysicsFromLOD(S32 lod);
 +	BOOL render();
 +	void update();
 +	void genBuffers(S32 lod, bool skinned);
 +	void clearBuffers();
 +	void refresh();
 +	void rotate(F32 yaw_radians, F32 pitch_radians);
 +	void zoom(F32 zoom_amt);
 +	void pan(F32 right, F32 up);
 +	virtual BOOL needsRender() { return mNeedsUpdate; }
 +	void setPreviewLOD(S32 lod);
 +	void clearModel(S32 lod);
 +	void loadModel(std::string filename, S32 lod);
 +	void loadModelCallback(S32 lod);
 +	void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false);
 +	void generateNormals();
 +	void clearMaterials();
 +	U32 calcResourceCost();
 +	void rebuildUploadData();
 +	void saveUploadData(bool save_skinweights, bool save_joint_poisitions);
 +	void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_poisitions);
 +	void clearIncompatible(S32 lod);
 +	void updateStatusMessages();
 +	void clearGLODGroup();
 +	void onLODParamCommit(bool enforce_tri_limit);
 +
 +	const bool getModelPivot( void ) const { return mHasPivot; }
 +	void setHasPivot( bool val ) { mHasPivot = val; }
 +	void setModelPivot( const LLVector3& pivot ) { mModelPivot = pivot; }
 +
 +	//Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps)
 +	void critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset );
 +	void critiqueJointToNodeMappingFromScene( void  );
 +	//Is a rig valid so that it can be used as a criteria for allowing for uploading of joint positions
 +	//Accessors for joint position upload friendly rigs
 +	const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; }
 +	void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; }
 +	bool isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset );
 +	//Determines if a rig is a legacy from the joint list
 +	bool isRigLegacy( const std::vector<std::string> &jointListFromAsset );	
 +	//Accessors for the legacy rigs
 +	const bool isLegacyRigValid( void ) const { return mLegacyRigValid; }
 +	void setLegacyRigValid( bool rigValid ) { mLegacyRigValid = rigValid; }	
 +	//Verify that a controller matches vertex counts
 +	bool verifyController( domController* pController );
 +
 +	static void	textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );
 +	
 +	boost::signals2::connection setDetailsCallback( const details_signal_t::slot_type& cb ){  return mDetailsSignal.connect(cb);  }
 +	boost::signals2::connection setModelLoadedCallback( const model_loaded_signal_t::slot_type& cb ){  return mModelLoadedSignal.connect(cb);  }
 +	
 +	void setLoadState( U32 state ) { mLoadState = state; }
 +	U32 getLoadState() { return mLoadState; }
 +	//setRestJointFlag: If an asset comes through that changes the joints, we want the reset to persist
 +	void setResetJointFlag( bool state ) { if ( !mResetJoints ) mResetJoints = state; }
 +	const bool getResetJointFlag( void ) const { return mResetJoints; }
 +	void setRigWithSceneParity( bool state ) { mRigParityWithScene = state; }
 +	const bool getRigWithSceneParity( void ) const { return mRigParityWithScene; }
 +	
 +	LLVector3 getTranslationForJointOffset( std::string joint );
 +
 +private:
 +	//Utility function for controller vertex compare
 +	bool verifyCount( int expected, int result );
 +	//Creates the dummy avatar for the preview window
 +	void		createPreviewAvatar( void );
 +	//Accessor for the dummy avatar
 +	LLVOAvatar* getPreviewAvatar( void ) { return mPreviewAvatar; }
 +
 + protected:
 +	friend class LLModelLoader;
 +	friend class LLFloaterModelPreview;
 +	friend class LLFloaterModelWizard;
 +	friend class LLFloaterModelPreview::DecompRequest;
 +	friend class LLFloaterModelWizard::DecompRequest;
 +	friend class LLPhysicsDecomp;
 +
 +	LLFloater*  mFMP;
 +
 +	BOOL        mNeedsUpdate;
 +	bool		mDirty;
 +	bool		mGenLOD;
 +	U32         mTextureName;
 +	F32			mCameraDistance;
 +	F32			mCameraYaw;
 +	F32			mCameraPitch;
 +	F32			mCameraZoom;
 +	LLVector3	mCameraOffset;
 +	LLVector3	mPreviewTarget;
 +	LLVector3	mPreviewScale;
 +	S32			mPreviewLOD;
 +	U32			mResourceCost;
 +	std::string mLODFile[LLModel::NUM_LODS];
 +	bool		mLoading;
 +	U32			mLoadState;
 +	bool		mResetJoints;
 +	bool		mRigParityWithScene;
 +	
 +	std::map<std::string, bool> mViewOption;
 +
 +	//GLOD object parameters (must rebuild object if these change)
 +	bool mLODFrozen;
 +	F32 mBuildShareTolerance;
 +	U32 mBuildQueueMode;
 +	U32 mBuildOperator;
 +	U32 mBuildBorderMode;
 +	U32 mRequestedLoDMode[LLModel::NUM_LODS];
 +	S32 mRequestedTriangleCount[LLModel::NUM_LODS];
 +	F32 mRequestedErrorThreshold[LLModel::NUM_LODS];
 +	U32 mRequestedBuildOperator[LLModel::NUM_LODS];
 +	U32 mRequestedQueueMode[LLModel::NUM_LODS];
 +	U32 mRequestedBorderMode[LLModel::NUM_LODS];
 +	F32 mRequestedShareTolerance[LLModel::NUM_LODS];
 +	F32 mRequestedCreaseAngle[LLModel::NUM_LODS];
 +
 +	LLModelLoader* mModelLoader;
 +
 +	LLModelLoader::scene mScene[LLModel::NUM_LODS];
 +	LLModelLoader::scene mBaseScene;
 +
 +	LLModelLoader::model_list mModel[LLModel::NUM_LODS];
 +	LLModelLoader::model_list mBaseModel;
 +
 +	U32 mGroup;
 +	std::map<LLPointer<LLModel>, U32> mObject;
 +	U32 mMaxTriangleLimit;
 +	
 +	LLMeshUploadThread::instance_list mUploadData;
 +	std::set<LLViewerFetchedTexture* > mTextureSet;
 +
 +	//map of vertex buffers to models (one vertex buffer in vector per face in model
 +	std::map<LLModel*, std::vector<LLPointer<LLVertexBuffer> > > mVertexBuffer[LLModel::NUM_LODS+1];
 +
 +	details_signal_t mDetailsSignal;
 +	model_loaded_signal_t mModelLoadedSignal;
 +	
 +	LLVector3	mModelPivot;
 +	bool		mHasPivot;
 +	
 +	float		mPelvisZOffset;
 +	
 +	bool		mRigValidJointUpload;
 +	bool		mLegacyRigValid;
 +
 +	bool		mLastJointUpdate;
 +
 +	std::deque<std::string> mMasterJointList;
 +	std::deque<std::string> mMasterLegacyJointList;
 +	std::deque<std::string> mJointsFromNode;
 +	JointTransformMap		mJointTransformMap;
 +	LLPointer<LLVOAvatar>	mPreviewAvatar;
 +};
 +
 +#endif  // LL_LLFLOATERMODELPREVIEW_H
 diff --git a/indra/newview/llfloatermodelwizard.cpp b/indra/newview/llfloatermodelwizard.cpp index faf81dbc5c..707c8288df 100644 --- a/indra/newview/llfloatermodelwizard.cpp +++ b/indra/newview/llfloatermodelwizard.cpp @@ -422,8 +422,11 @@ void LLFloaterModelWizard::executePhysicsStage(std::string stage_name)  			{  				LLModel* mdl = sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS][i];  				DecompRequest* request = new DecompRequest(stage_name, mdl); -				sInstance->mCurRequest.insert(request); -				gMeshRepo.mDecompThread->submitRequest(request); +				if(request->isValid()) +				{ +					sInstance->mCurRequest.insert(request); +					gMeshRepo.mDecompThread->submitRequest(request); +				}				  			}  		}  	} @@ -438,35 +441,7 @@ LLFloaterModelWizard::DecompRequest::DecompRequest(const std::string& stage, LLM  	mParams = sInstance->mDecompParams;  	//copy out positions and indices -	if (mdl) -	{ -		U16 index_offset = 0; - -		mPositions.clear(); -		mIndices.clear(); - -		//queue up vertex positions and indices -		for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) -		{ -			const LLVolumeFace& face = mdl->getVolumeFace(i); -			if (mPositions.size() + face.mNumVertices > 65535) -			{ -				continue; -			} - -			for (U32 j = 0; j < face.mNumVertices; ++j) -			{ -				mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr())); -			} - -			for (U32 j = 0; j < face.mNumIndices; ++j) -			{ -				mIndices.push_back(face.mIndices[j]+index_offset); -			} - -			index_offset += face.mNumVertices; -		} -	} +	assignData(mdl) ;	  } diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 232b8e9096..6b3e3088d5 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -82,6 +82,7 @@  #include "llvlcomposition.h"  #include "lltrans.h"  #include "llagentui.h" +#include "llmeshrepository.h"  const S32 TERRAIN_TEXTURE_COUNT = 4;  const S32 CORNER_COUNT = 4; @@ -590,10 +591,7 @@ bool LLPanelRegionGeneralInfo::refreshFromRegion(LLViewerRegion* region)  	getChildView("im_btn")->setEnabled(allow_modify);  	getChildView("manage_telehub_btn")->setEnabled(allow_modify); -	const bool enable_mesh = gSavedSettings.getBOOL("MeshEnabled") &&  -		gAgent.getRegion() && -		!gAgent.getRegion()->getCapability("GetMesh").empty() && -		!gAgent.getRegion()->getCapability("ObjectAdd").empty(); +	const bool enable_mesh = gMeshRepo.meshRezEnabled();  	getChildView("mesh_rez_enabled_check")->setVisible(enable_mesh);  	getChildView("mesh_rez_enabled_check")->setEnabled(getChildView("mesh_rez_enabled_check")->getEnabled() && enable_mesh);  	// Data gets filled in by processRegionInfo diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index edcb96314b..0d798afdcc 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -86,6 +86,7 @@  #include "llvovolume.h"  #include "lluictrlfactory.h"  #include "llaccountingquotamanager.h" +#include "llmeshrepository.h"  // Globals  LLFloaterTools *gFloaterTools = NULL; @@ -423,7 +424,8 @@ void LLFloaterTools::refresh()  	// Refresh object and prim count labels  	LLLocale locale(LLLocale::USER_LOCALE); -	if ((gAgent.getRegion() && (gAgent.getRegion()->getCapability("GetMesh").empty() || gAgent.getRegion()->getCapability("ObjectAdd").empty())) || !gSavedSettings.getBOOL("MeshEnabled")) +#if 0 +	if (gMeshRepo.meshRezEnabled())  	{		  		std::string obj_count_string;  		LLResMgr::getInstance()->getIntegerString(obj_count_string, LLSelectMgr::getInstance()->getSelection()->getRootObjectCount()); @@ -447,6 +449,7 @@ void LLFloaterTools::refresh()  		getChildView("RenderingCost")->setEnabled(have_selection && sShowObjectCost);  	}  	else +#endif  	{  		// Get the number of objects selected  		std::string root_object_count_string; @@ -788,10 +791,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)  		getChildView("Strength:")->setVisible( land_visible);  	} -	bool show_mesh_cost = gAgent.getRegion() &&  -		                  !gAgent.getRegion()->getCapability("GetMesh").empty() &&  -						  gSavedSettings.getBOOL("MeshEnabled") && -						  !gAgent.getRegion()->getCapability("ObjectAdd").empty(); +	bool show_mesh_cost = gMeshRepo.meshRezEnabled();  	getChildView("obj_count")->setVisible( !land_visible && !show_mesh_cost);  	getChildView("prim_count")->setVisible( !land_visible && !show_mesh_cost); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index b5180854ef..318beafe65 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -632,10 +632,12 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)  	}  	// We're hiding mesh types +#if 0  	if (item->getType() == LLAssetType::AT_MESH)  	{  		return mask;  	} +#endif  	LLViewerInventoryItem* old_item = getItem(item->getUUID());  	LLPointer<LLViewerInventoryItem> new_item; diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index 673f28e01f..4eb94dfb8e 100644 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -58,6 +58,7 @@  #include "llworld.h"  #include "v2math.h"  #include "llvoavatar.h" +#include "llmeshrepository.h"  const F32 MAX_MANIP_SELECT_DISTANCE_SQUARED = 11.f * 11.f; @@ -90,10 +91,7 @@ F32 get_default_max_prim_scale(bool is_flora)  {  	// a bit of a hack, but if it's foilage, we don't want to use the  	// new larger scale which would result in giant trees and grass -	if (gSavedSettings.getBOOL("MeshEnabled") &&  -		gAgent.getRegion() &&  -		!gAgent.getRegion()->getCapability("GetMesh").empty() && -		!gAgent.getRegion()->getCapability("ObjectAdd").empty() && +	if (gMeshRepo.meshRezEnabled() &&  		!is_flora)  	{  		return DEFAULT_MAX_PRIM_SCALE; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 55145c6ad7..6e0722bcf9 100644..100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -61,6 +61,9 @@  #include "pipeline.h"  #include "llinventorymodel.h"  #include "llfoldertype.h" +#include "llviewerparcelmgr.h" + +#include "boost/lexical_cast.hpp"  #ifndef LL_WINDOWS  #include "netdb.h" @@ -85,7 +88,14 @@ U32 LLMeshRepository::sPeakKbps = 0;  const U32 MAX_TEXTURE_UPLOAD_RETRIES = 5; -void dumpLLSDToFile(const LLSD& content, std::string filename); +static S32 dump_num = 0; +std::string make_dump_name(std::string prefix, S32 num) +{ +	return prefix + boost::lexical_cast<std::string>(num) + std::string(".xml"); +	 +} +void dump_llsd_to_file(const LLSD& content, std::string filename); +LLSD llsd_from_file(std::string filename);  std::string header_lod[] =   { @@ -459,6 +469,55 @@ public:  }; +void log_upload_error(S32 status, const LLSD& content, std::string stage, std::string model_name) +{ +	// Add notification popup. +	LLSD args; +	std::string message = content["error"]["message"]; +	std::string identifier = content["error"]["identifier"]; +	args["MESSAGE"] = message; +	args["IDENTIFIER"] = identifier; +	args["LABEL"] = model_name; +	gMeshRepo.uploadError(args); + +	// Log details. +	llwarns << "stage: " << stage << " http status: " << status << llendl; +	if (content.has("error")) +	{ +		const LLSD& err = content["error"]; +		llwarns << "err: " << err << llendl; +		llwarns << "mesh upload failed, stage '" << stage +				<< "' error '" << err["error"].asString() +				<< "', message '" << err["message"].asString() +				<< "', id '" << err["identifier"].asString() +				<< "'" << llendl; +		if (err.has("errors")) +		{ +			S32 error_num = 0; +			const LLSD& err_list = err["errors"]; +			for (LLSD::array_const_iterator it = err_list.beginArray(); +				 it != err_list.endArray(); +				 ++it) +			{ +				const LLSD& err_entry = *it; +				llwarns << "error[" << error_num << "]:" << llendl; +				for (LLSD::map_const_iterator map_it = err_entry.beginMap(); +					 map_it != err_entry.endMap(); +					 ++map_it) +				{ +					llwarns << "\t" << map_it->first << ": " +							<< map_it->second << llendl; +				} +				error_num++; +			} +		} +	} +	else +	{ +		llwarns << "bad mesh, no error information available" << llendl; +	} +} +  class LLModelObjectUploadResponder: public LLCurl::Responder  {  	LLSD mObjectAsset; @@ -486,40 +545,82 @@ public:  class LLWholeModelFeeResponder: public LLCurl::Responder  {  	LLMeshUploadThread* mThread; +	LLSD mModelData;  public: -	LLWholeModelFeeResponder(LLMeshUploadThread* thread): -		mThread(thread) +	LLWholeModelFeeResponder(LLMeshUploadThread* thread, LLSD& model_data): +		mThread(thread), +		mModelData(model_data)  	{  	}  	virtual void completed(U32 status,  						   const std::string& reason,  						   const LLSD& content)  	{ -		//assert_main_thread(); +		LLSD cc = content; +		if (gSavedSettings.getS32("MeshUploadFakeErrors")&1) +		{ +			cc = llsd_from_file("fake_upload_error.xml"); +		} +			  		llinfos << "completed" << llendl;  		mThread->mPendingUploads--; -		dumpLLSDToFile(content,"whole_model_response.xml"); - -		mThread->mWholeModelUploadURL = content["uploader"].asString();  +		dump_llsd_to_file(cc,make_dump_name("whole_model_fee_response_",dump_num)); +		if (isGoodStatus(status) && +			cc["state"].asString() == "upload") +		{ +			llinfos << "fee request succeeded" << llendl; +			mThread->mWholeModelUploadURL = cc["uploader"].asString();  +		} +		else +		{ +			llwarns << "fee request failed" << llendl; +			log_upload_error(status,cc,"fee",mModelData["name"]); +			mThread->mWholeModelUploadURL = ""; +		}  	} +  };  class LLWholeModelUploadResponder: public LLCurl::Responder  {  	LLMeshUploadThread* mThread; +	LLSD mModelData; +	  public: -	LLWholeModelUploadResponder(LLMeshUploadThread* thread): -		mThread(thread) +	LLWholeModelUploadResponder(LLMeshUploadThread* thread, LLSD& model_data): +		mThread(thread), +		mModelData(model_data)  	{  	}  	virtual void completed(U32 status,  						   const std::string& reason,  						   const LLSD& content)  	{ +		LLSD cc = content; +		if (gSavedSettings.getS32("MeshUploadFakeErrors")&2) +		{ +			cc = llsd_from_file("fake_upload_error.xml"); +		} +  		//assert_main_thread(); -		llinfos << "upload completed" << llendl;  		mThread->mPendingUploads--; -		dumpLLSDToFile(content,"whole_model_upload_response.xml"); +		dump_llsd_to_file(cc,make_dump_name("whole_model_upload_response_",dump_num)); +		llinfos << "LLWholeModelUploadResponder content: " << cc << llendl; +		// requested "mesh" asset type isn't actually the type +		// of the resultant object, fix it up here. +		if (isGoodStatus(status) && +			cc["state"].asString() == "complete") +		{ +			llinfos << "upload succeeded" << llendl; +			mModelData["asset_type"] = "object"; +			gMeshRepo.updateInventory(LLMeshRepository::inventory_data(mModelData,cc)); +		} +		else +		{ +			llwarns << "upload failed" << llendl; +			std::string model_name = mModelData["name"].asString(); +			log_upload_error(status,cc,"upload",model_name); +		}  	}  }; @@ -694,10 +795,7 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)  		if (pending != mPendingLOD.end())  		{ //append this lod request to existing header request  			pending->second.push_back(lod); -			if (pending->second.size() > 4) -			{ -				llerrs << "WTF?" << llendl; -			}  +			llassert(pending->second.size() <= LLModel::NUM_LODS)  		}  		else  		{ //if no header request is pending, fetch header @@ -817,8 +915,8 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)  	if (header_size > 0)  	{ -		S32 offset = header_size + mMeshHeader[mesh_id]["decomposition"]["offset"].asInteger(); -		S32 size = mMeshHeader[mesh_id]["decomposition"]["size"].asInteger(); +		S32 offset = header_size + mMeshHeader[mesh_id]["physics_convex"]["offset"].asInteger(); +		S32 size = mMeshHeader[mesh_id]["physics_convex"]["size"].asInteger();  		mHeaderMutex->unlock(); @@ -889,8 +987,8 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)  	if (header_size > 0)  	{ -		S32 offset = header_size + mMeshHeader[mesh_id]["physics_shape"]["offset"].asInteger(); -		S32 size = mMeshHeader[mesh_id]["physics_shape"]["size"].asInteger(); +		S32 offset = header_size + mMeshHeader[mesh_id]["physics_mesh"]["offset"].asInteger(); +		S32 size = mMeshHeader[mesh_id]["physics_mesh"]["size"].asInteger();  		mHeaderMutex->unlock(); @@ -1282,8 +1380,6 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,  	mOrigin = gAgent.getPositionAgent();  	mHost = gAgent.getRegionHost(); -	mUploadObjectAssetCapability = gAgent.getRegion()->getCapability("UploadObjectAsset"); -	mNewInventoryCapability = gAgent.getRegion()->getCapability("NewFileAgentInventoryVariablePrice");  	mWholeModelFeeCapability = gAgent.getRegion()->getCapability("NewFileAgentInventory");  	mOrigin += gAgent.getAtAxis() * scale.magVec(); @@ -1303,35 +1399,7 @@ LLMeshUploadThread::DecompRequest::DecompRequest(LLModel* mdl, LLModel* base_mod  	mThread = thread;  	//copy out positions and indices -	if (mdl) -	{ -		U16 index_offset = 0; - -		mPositions.clear(); -		mIndices.clear(); -			 -		//queue up vertex positions and indices -		for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) -		{ -			const LLVolumeFace& face = mdl->getVolumeFace(i); -			if (mPositions.size() + face.mNumVertices > 65535) -			{ -				continue; -			} - -			for (U32 j = 0; j < face.mNumVertices; ++j) -			{ -				mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr())); -			} - -			for (U32 j = 0; j < face.mNumIndices; ++j) -			{ -				mIndices.push_back(face.mIndices[j]+index_offset); -			} - -			index_offset += face.mNumVertices; -		} -	} +	assignData(mdl) ;	  	mThread->mFinalDecomp = this;  	mThread->mPhysicsComplete = false; @@ -1344,11 +1412,8 @@ void LLMeshUploadThread::DecompRequest::completed()  		mThread->mPhysicsComplete = true;  	} -	if (mHull.size() != 1) -	{ -		llerrs << "WTF?" << llendl; -	} - +	llassert(mHull.size() == 1); +	  	mThread->mHullMap[mBaseModel] = mHull[0];  } @@ -1376,148 +1441,199 @@ BOOL LLMeshUploadThread::isDiscarded()  void LLMeshUploadThread::run()  { -	if (gSavedSettings.getBOOL("MeshUseWholeModelUpload")) -	{ -		doWholeModelUpload(); -	} -	else +	doWholeModelUpload(); +} + +void dump_llsd_to_file(const LLSD& content, std::string filename) +{ +	if (gSavedSettings.getBOOL("MeshUploadLogXML"))  	{ -		doIterativeUpload(); +		std::ofstream of(filename.c_str()); +		LLSDSerialize::toPrettyXML(content,of);  	}  } -#if 1 -void dumpLLSDToFile(const LLSD& content, std::string filename) +LLSD llsd_from_file(std::string filename)  { -	std::ofstream of(filename.c_str()); -	LLSDSerialize::toPrettyXML(content,of); +	std::ifstream ifs(filename.c_str()); +	LLSD result; +	LLSDSerialize::fromXML(result,ifs); +	return result;  } -#endif  void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)  { -	// TODO where do textures go? -  	LLSD result;  	LLSD res;  	result["folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);  	result["asset_type"] = "mesh";  	result["inventory_type"] = "object"; -	result["name"] = "your name here"; +	result["name"] = "mesh model";  	result["description"] = "your description here"; -	// TODO "optional" fields from the spec -	  	res["mesh_list"] = LLSD::emptyArray(); -// TODO Textures -	//res["texture_list"] = LLSD::emptyArray(); +	res["texture_list"] = LLSD::emptyArray(); +	res["instance_list"] = LLSD::emptyArray();  	S32 mesh_num = 0;  	S32 texture_num = 0;  	std::set<LLViewerTexture* > textures; +	std::map<LLViewerTexture*,S32> texture_index; + +	std::map<LLModel*,S32> mesh_index; +	S32 instance_num = 0; +	  	for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter)  	{  		LLMeshUploadData data;  		data.mBaseModel = iter->first; - -		LLModelInstance& instance = *(iter->second.begin()); - +		LLModelInstance& first_instance = *(iter->second.begin());  		for (S32 i = 0; i < 5; i++)  		{ -			data.mModel[i] = instance.mLOD[i]; +			data.mModel[i] = first_instance.mLOD[i];  		} -		std::stringstream ostr; - -		LLModel::Decomposition& decomp = -			data.mModel[LLModel::LOD_PHYSICS].notNull() ?  -			data.mModel[LLModel::LOD_PHYSICS]->mPhysics :  -			data.mBaseModel->mPhysics; - -		decomp.mBaseHull = mHullMap[data.mBaseModel]; - -		LLSD mesh_header = LLModel::writeModel( -			ostr,   -			data.mModel[LLModel::LOD_PHYSICS], -			data.mModel[LLModel::LOD_HIGH], -			data.mModel[LLModel::LOD_MEDIUM], -			data.mModel[LLModel::LOD_LOW], -			data.mModel[LLModel::LOD_IMPOSTOR],  -			decomp, -			mUploadSkin, -			mUploadJoints); - -		data.mAssetData = ostr.str(); +		if (mesh_index.find(data.mBaseModel) == mesh_index.end()) +		{ +			// Have not seen this model before - create a new mesh_list entry for it. +			std::string model_name = data.mBaseModel->getName(); +			if (!model_name.empty()) +			{ +				result["name"] = model_name; +			} -		LLSD mesh_entry; +			std::stringstream ostr; +			 +			LLModel::Decomposition& decomp = +				data.mModel[LLModel::LOD_PHYSICS].notNull() ?  +				data.mModel[LLModel::LOD_PHYSICS]->mPhysics :  +				data.mBaseModel->mPhysics; -		LLVector3 pos, scale; -		LLQuaternion rot; -		LLMatrix4 transformation = instance.mTransform; -		decomposeMeshMatrix(transformation,pos,rot,scale); +			decomp.mBaseHull = mHullMap[data.mBaseModel]; -#if 0 -		mesh_entry["childpos"] = ll_sd_from_vector3(pos); -		mesh_entry["childrot"] = ll_sd_from_quaternion(rot); -		mesh_entry["scale"] = ll_sd_from_vector3(scale); -#endif -		mesh_entry["position"] = ll_sd_from_vector3(LLVector3()); -		mesh_entry["rotation"] = ll_sd_from_quaternion(rot); -		mesh_entry["scale"] = ll_sd_from_vector3(scale); +			LLSD mesh_header = LLModel::writeModel( +				ostr,   +				data.mModel[LLModel::LOD_PHYSICS], +				data.mModel[LLModel::LOD_HIGH], +				data.mModel[LLModel::LOD_MEDIUM], +				data.mModel[LLModel::LOD_LOW], +				data.mModel[LLModel::LOD_IMPOSTOR],  +				decomp, +				mUploadSkin, +				mUploadJoints); -		// TODO should be binary. -		std::string str = ostr.str(); -		mesh_entry["mesh_data"] = LLSD::Binary(str.begin(),str.end());  +			data.mAssetData = ostr.str(); +			std::string str = ostr.str(); -		res["mesh_list"][mesh_num] = mesh_entry; +			res["mesh_list"][mesh_num] = LLSD::Binary(str.begin(),str.end());  +			mesh_index[data.mBaseModel] = mesh_num; +			mesh_num++; +		} -		// TODO how do textures in the list map to textures in the meshes? -		if (mUploadTextures) +		// For all instances that use this model +		for (instance_list::iterator instance_iter = iter->second.begin(); +			 instance_iter != iter->second.end(); +			 ++instance_iter)  		{ -			for (std::vector<LLImportMaterial>::iterator material_iter = instance.mMaterial.begin(); -				material_iter != instance.mMaterial.end(); ++material_iter) -			{ -				if (textures.find(material_iter->mDiffuseMap.get()) == textures.end()) +			LLModelInstance& instance = *instance_iter; +		 +			LLSD instance_entry; +		 +			for (S32 i = 0; i < 5; i++) +			{ +				data.mModel[i] = instance.mLOD[i]; +			} +		 +			LLVector3 pos, scale; +			LLQuaternion rot; +			LLMatrix4 transformation = instance.mTransform; +			decomposeMeshMatrix(transformation,pos,rot,scale); +			instance_entry["position"] = ll_sd_from_vector3(pos); +			instance_entry["rotation"] = ll_sd_from_quaternion(rot); +			instance_entry["scale"] = ll_sd_from_vector3(scale); +		 +			instance_entry["material"] = LL_MCODE_WOOD; +			LLPermissions perm; +			perm.setOwnerAndGroup(gAgent.getID(), gAgent.getID(), LLUUID::null, false); +			perm.setCreator(gAgent.getID()); +		 +			perm.initMasks(PERM_ITEM_UNRESTRICTED | PERM_MOVE, //base +						   PERM_ITEM_UNRESTRICTED | PERM_MOVE, //owner +						   LLFloaterPerms::getEveryonePerms(), +						   LLFloaterPerms::getGroupPerms(), +						   LLFloaterPerms::getNextOwnerPerms()); +			instance_entry["permissions"] = ll_create_sd_from_permissions(perm); +			instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL); +			instance_entry["mesh"] = mesh_index[data.mBaseModel]; + +			instance_entry["face_list"] = LLSD::emptyArray(); + +			for (S32 face_num = 0; face_num < data.mBaseModel->getNumVolumeFaces(); face_num++) +			{ +				LLImportMaterial& material = instance.mMaterial[face_num]; +				LLSD face_entry = LLSD::emptyMap(); +				LLViewerFetchedTexture *texture = material.mDiffuseMap.get(); +				 +				if ((texture != NULL) && +					(textures.find(texture) == textures.end()))  				{ -					textures.insert(material_iter->mDiffuseMap.get()); +					textures.insert(texture); +				} -					std::stringstream ostr; -					if (include_textures) // otherwise data is blank. -					{ -						LLTextureUploadData data(material_iter->mDiffuseMap.get(), material_iter->mDiffuseMapLabel); -						if (!data.mTexture->isRawImageValid()) -						{ -							data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel()); -						} -						 +				std::stringstream texture_str; +				if (texture != NULL && include_textures && mUploadTextures) +				{ +					if(texture->hasSavedRawImage()) +					{											  						LLPointer<LLImageJ2C> upload_file = -							LLViewerTextureList::convertToUploadFile(data.mTexture->getRawImage()); -						ostr.write((const char*) upload_file->getData(), upload_file->getDataSize()); +							LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage()); +						texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize());  					} -					LLSD texture_entry; -					texture_entry["texture_data"] = ostr.str(); -					res["texture_list"][texture_num] = texture_entry; +				} + +				if (texture != NULL && +					mUploadTextures && +					texture_index.find(texture) == texture_index.end()) +				{ +					texture_index[texture] = texture_num; +					std::string str = texture_str.str(); +					res["texture_list"][texture_num] = LLSD::Binary(str.begin(),str.end());  					texture_num++;  				} -			} -		} -		mesh_num++; +				// Subset of TextureEntry fields. +				if (texture != NULL && mUploadTextures) +				{ +					face_entry["image"] = texture_index[texture]; +					face_entry["scales"] = 1.0; +					face_entry["scalet"] = 1.0; +					face_entry["offsets"] = 0.0; +					face_entry["offsett"] = 0.0; +					face_entry["imagerot"] = 0.0; +				} +				face_entry["diffuse_color"] = ll_sd_from_color4(material.mDiffuseColor); +				face_entry["fullbright"] = material.mFullbright; +				instance_entry["face_list"][face_num] = face_entry; +		    } + +			res["instance_list"][instance_num] = instance_entry; +			instance_num++; +		}  	}  	result["asset_resources"] = res; -#if 1	 -	dumpLLSDToFile(result,"whole_model.xml"); -#endif +	dump_llsd_to_file(result,make_dump_name("whole_model_",dump_num));  	dest = result;  }  void LLMeshUploadThread::doWholeModelUpload()  { +	dump_num++; +	  	mCurlRequest = new LLCurlRequest();	  	// Queue up models for hull generation (viewer-side) @@ -1549,13 +1665,13 @@ void LLMeshUploadThread::doWholeModelUpload()  			physics = data.mModel[LLModel::LOD_HIGH];  		} -		if (!physics) -		{ -			llerrs << "WTF?" << llendl; -		} - +		llassert(physics != NULL); +		  		DecompRequest* request = new DecompRequest(physics, data.mBaseModel, this); -		gMeshRepo.mDecompThread->submitRequest(request); +		if(request->isValid()) +		{ +			gMeshRepo.mDecompThread->submitRequest(request); +		}		  	}  	while (!mPhysicsComplete) @@ -1563,183 +1679,44 @@ void LLMeshUploadThread::doWholeModelUpload()  		apr_sleep(100);  	} -	bool do_include_textures = false; // not needed for initial cost/validation check.  	LLSD model_data; -	wholeModelToLLSD(model_data, do_include_textures); +	wholeModelToLLSD(model_data,false); +	dump_llsd_to_file(model_data,make_dump_name("whole_model_fee_request_",dump_num));  	mPendingUploads++;  	LLCurlRequest::headers_t headers;  	mCurlRequest->post(mWholeModelFeeCapability, headers, model_data, -					   new LLWholeModelFeeResponder(this)); +					   new LLWholeModelFeeResponder(this,model_data));  	do  	{  		mCurlRequest->process();  	} while (mCurlRequest->getQueued() > 0); -	mCurlRequest->post(mWholeModelUploadURL, headers, model_data["asset_resources"], new LLWholeModelUploadResponder(this)); -	 -	do -	{ -		mCurlRequest->process(); -	} while (mCurlRequest->getQueued() > 0); - -	delete mCurlRequest; -	mCurlRequest = NULL; - -	// Currently a no-op. -	mFinished = true; -} - -void LLMeshUploadThread::doIterativeUpload() -{ -	if(isDiscarded()) -	{ -		mFinished = true; -		return ; -	} -	 -	mCurlRequest = new LLCurlRequest();	 - -	std::set<LLViewerTexture* > textures; - -	//populate upload queue with relevant models -	for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter) -	{ -		LLMeshUploadData data; -		data.mBaseModel = iter->first; - -		LLModelInstance& instance = *(iter->second.begin()); - -		for (S32 i = 0; i < 5; i++) -		{ -			data.mModel[i] = instance.mLOD[i]; -		} - -		uploadModel(data); - -		if (mUploadTextures) -		{ -			for (std::vector<LLImportMaterial>::iterator material_iter = instance.mMaterial.begin(); -				material_iter != instance.mMaterial.end(); ++material_iter) -			{ - -				if (textures.find(material_iter->mDiffuseMap.get()) == textures.end()) -				{ -					textures.insert(material_iter->mDiffuseMap.get()); -					 -					LLTextureUploadData data(material_iter->mDiffuseMap.get(), material_iter->mDiffuseMapLabel); -					uploadTexture(data); -				} -			} -		} - -		//queue up models for hull generation -		DecompRequest* request = new DecompRequest(data.mModel[LLModel::LOD_HIGH], data.mBaseModel, this); -		gMeshRepo.mDecompThread->submitRequest(request); -	} -	while (!mPhysicsComplete) +	if (mWholeModelUploadURL.empty())  	{ -		apr_sleep(100); -	} - -	//upload textures -	bool done = false; -	do -	{ -		if (!mTextureQ.empty()) -		{ -			sendCostRequest(mTextureQ.front()); -			mTextureQ.pop(); -		} - -		if (!mConfirmedTextureQ.empty()) -		{ -			doUploadTexture(mConfirmedTextureQ.front()); -			mConfirmedTextureQ.pop(); -		} - -		mCurlRequest->process(); - -		done = mTextureQ.empty() && mConfirmedTextureQ.empty(); +		llinfos << "unable to upload, fee request failed" << llendl;  	} -	while (!done || mCurlRequest->getQueued() > 0); - -	LLSD object_asset; -	object_asset["objects"] = LLSD::emptyArray(); - -	done = false; -	do  +	else  	{ -		static S32 count = 0; -		static F32 last_hundred = gFrameTimeSeconds; -		if (gFrameTimeSeconds - last_hundred > 1.f) +		LLSD full_model_data; +		wholeModelToLLSD(full_model_data, true); +		LLSD body = full_model_data["asset_resources"]; +		dump_llsd_to_file(body,make_dump_name("whole_model_body_",dump_num)); +		mCurlRequest->post(mWholeModelUploadURL, headers, body, +						   new LLWholeModelUploadResponder(this, model_data)); +		do  		{ -			last_hundred = gFrameTimeSeconds; -			count = 0; -		} - -		//how many requests to push before calling process -		const S32 PUSH_PER_PROCESS = 32; - -		S32 tcount = llmin(count+PUSH_PER_PROCESS, 100); - -		while (!mUploadQ.empty() && count < tcount) -		{ //send any pending upload requests -			mMutex->lock(); -			LLMeshUploadData data = mUploadQ.front(); -			mUploadQ.pop(); -			mMutex->unlock(); -			sendCostRequest(data); -			count++; -		} - -		tcount = llmin(count+PUSH_PER_PROCESS, 100); -		 -		while (!mConfirmedQ.empty() && count < tcount) -		{ //process any meshes that have been confirmed for upload -			LLMeshUploadData& data = mConfirmedQ.front(); -			doUploadModel(data); -			mConfirmedQ.pop(); -			count++; -		} -	 -		tcount = llmin(count+PUSH_PER_PROCESS, 100); - -		while (!mInstanceQ.empty() && count < tcount && !isDiscarded()) -		{ //create any objects waiting for upload -			count++; -			object_asset["objects"].append(createObject(mInstanceQ.front())); -			mInstanceQ.pop(); -		} -			 -		mCurlRequest->process(); -			 -		done = isDiscarded() || (mInstanceQ.empty() && mConfirmedQ.empty() && mUploadQ.empty()); +			mCurlRequest->process(); +		} while (mCurlRequest->getQueued() > 0);  	} -	while (!done || mCurlRequest->getQueued() > 0);  	delete mCurlRequest;  	mCurlRequest = NULL; -	// now upload the object asset -	std::string url = mUploadObjectAssetCapability; - -	if (object_asset["objects"][0].has("permissions")) -	{ //copy permissions from first available object to be used for coalesced object -		object_asset["permissions"] = object_asset["objects"][0]["permissions"]; -	} - -	if(!isDiscarded()) -	{ -		mPendingUploads++; -		LLHTTPClient::post(url, object_asset, new LLModelObjectUploadResponder(this,object_asset)); -	} -	else -	{ -		mFinished = true; -	} +	// Currently a no-op. +	mFinished = true;  }  void LLMeshUploadThread::uploadModel(LLMeshUploadData& data) @@ -2170,7 +2147,7 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,  		//just in case skin info or decomposition is at the end of the file (which it shouldn't be)  		lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger()); -		lod_bytes = llmax(lod_bytes, header["decomposition"]["offset"].asInteger() + header["decomposition"]["size"].asInteger()); +		lod_bytes = llmax(lod_bytes, header["physics_convex"]["offset"].asInteger() + header["physics_convex"]["size"].asInteger());  		S32 header_bytes = (S32) gMeshRepo.mThread->mMeshHeaderSize[mesh_id];  		S32 bytes = lod_bytes + header_bytes;  @@ -2387,10 +2364,6 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para  				group->derefLOD(lod);  			}  		} -		else -		{ -			llerrs << "WTF?" << llendl; -		}  	}  	return detail; @@ -2462,7 +2435,6 @@ void LLMeshRepository::notifyLoadedMeshes()  		if (gAgent.getRegion()->getName() != region_name && gAgent.getRegion()->capabilitiesReceived())  		{  			region_name = gAgent.getRegion()->getName(); -		  			mGetMeshCapability = gAgent.getRegion()->getCapability("GetMesh");  		}  	} @@ -2570,6 +2542,20 @@ void LLMeshRepository::notifyLoadedMeshes()  void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo& info)  {  	mSkinMap[info.mMeshID] = info; + +	skin_load_map::iterator iter = mLoadingSkins.find(info.mMeshID); +	if (iter != mLoadingSkins.end()) +	{ +		for (std::set<LLUUID>::iterator obj_id = iter->second.begin(); obj_id != iter->second.end(); ++obj_id) +		{ +			LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*obj_id); +			if (vobj) +			{ +				vobj->notifyMeshLoaded(); +			} +		} +	} +  	mLoadingSkins.erase(info.mMeshID);  } @@ -2685,7 +2671,7 @@ U32 LLMeshRepository::getResourceCost(const LLUUID& mesh_id)  	return mThread->getResourceCost(mesh_id);  } -const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id) +const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj)  {  	if (mesh_id.notNull())  	{ @@ -2699,12 +2685,12 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id)  		{  			LLMutexLock lock(mMeshMutex);  			//add volume to list of loading meshes -			std::set<LLUUID>::iterator iter = mLoadingSkins.find(mesh_id); +			skin_load_map::iterator iter = mLoadingSkins.find(mesh_id);  			if (iter == mLoadingSkins.end())  			{ //no request pending for this skin info -				mLoadingSkins.insert(mesh_id);  				mPendingSkinRequests.push(mesh_id);  			} +			mLoadingSkins[mesh_id].insert(requesting_obj->getID());  		}  	} @@ -2786,7 +2772,18 @@ void LLMeshRepository::buildHull(const LLVolumeParams& params, S32 detail)  bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id)  {  	LLSD mesh = mThread->getMeshHeader(mesh_id); -	return mesh.has("physics_shape") && mesh["physics_shape"].has("size") && (mesh["physics_shape"]["size"].asInteger() > 0); +	if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0)) +	{ +		return true; +	} + +	LLModel::Decomposition* decomp = getDecomposition(mesh_id); +	if (decomp && !decomp->mHull.empty()) +	{ +		return true; +	} + +	return false;  }  LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id) @@ -2842,102 +2839,6 @@ S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod)  } -void LLMeshUploadThread::sendCostRequest(LLMeshUploadData& data) -{ -	if(isDiscarded()) -	{ -		return ; -	} - -	//write model file to memory buffer -	std::stringstream ostr; - -	LLModel::Decomposition& decomp = -		data.mModel[LLModel::LOD_PHYSICS].notNull() ?  -		data.mModel[LLModel::LOD_PHYSICS]->mPhysics :  -		data.mBaseModel->mPhysics; - -	LLSD header = LLModel::writeModel( -		ostr, -		data.mModel[LLModel::LOD_PHYSICS], -		data.mModel[LLModel::LOD_HIGH], -		data.mModel[LLModel::LOD_MEDIUM], -		data.mModel[LLModel::LOD_LOW], -		data.mModel[LLModel::LOD_IMPOSTOR],  -		decomp, -		mUploadSkin, -		mUploadJoints, -		true); - -	std::string desc = data.mBaseModel->mLabel; -	 -	// Grab the total vertex count of the model -	// along with other information for the "asset_resources" map -	// to send to the server. -	LLSD asset_resources = LLSD::emptyMap(); - - -	std::string url = mNewInventoryCapability;  - -	if (!url.empty()) -	{ -		LLSD body = generate_new_resource_upload_capability_body( -			LLAssetType::AT_MESH, -			desc, -			desc, -			LLFolderType::FT_MESH, -			LLInventoryType::IT_MESH, -			LLFloaterPerms::getNextOwnerPerms(), -			LLFloaterPerms::getGroupPerms(), -			LLFloaterPerms::getEveryonePerms()); - -		body["asset_resources"] = asset_resources; - -		mPendingConfirmations++; -		LLCurlRequest::headers_t headers; - -		data.mPostData = body; - -		mCurlRequest->post(url, headers, body, new LLMeshCostResponder(data, this)); -	}	 -} - -void LLMeshUploadThread::sendCostRequest(LLTextureUploadData& data) -{ -	if(isDiscarded()) -	{ -		return ; -	} - -	if (data.mTexture && data.mTexture->getDiscardLevel() >= 0) -	{ -		LLSD asset_resources = LLSD::emptyMap(); - -		std::string url = mNewInventoryCapability;  - -		if (!url.empty()) -		{ -			LLSD body = generate_new_resource_upload_capability_body( -				LLAssetType::AT_TEXTURE, -				data.mLabel, -				data.mLabel, -				LLFolderType::FT_TEXTURE, -				LLInventoryType::IT_TEXTURE, -				LLFloaterPerms::getNextOwnerPerms(), -				LLFloaterPerms::getGroupPerms(), -				LLFloaterPerms::getEveryonePerms()); - -			body["asset_resources"] = asset_resources; - -			mPendingConfirmations++; -			LLCurlRequest::headers_t headers; -			 -			data.mPostData = body; -			mCurlRequest->post(url, headers, body, new LLTextureCostResponder(data, this)); -		}	 -	} -} -  void LLMeshUploadThread::doUploadModel(LLMeshUploadData& data)  { @@ -2993,9 +2894,12 @@ void LLMeshUploadThread::doUploadTexture(LLTextureUploadData& data)  			data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel());  		} -		LLPointer<LLImageJ2C> upload_file = LLViewerTextureList::convertToUploadFile(data.mTexture->getRawImage()); +		if(data.mTexture->hasSavedRawImage()) +		{ +			LLPointer<LLImageJ2C> upload_file = LLViewerTextureList::convertToUploadFile(data.mTexture->getSavedRawImage()); -		ostr.write((const char*) upload_file->getData(), upload_file->getDataSize()); +			ostr.write((const char*) upload_file->getData(), upload_file->getDataSize()); +		}  		data.mAssetData = ostr.str(); @@ -3075,11 +2979,8 @@ LLSD LLMeshUploadThread::createObject(LLModelInstance& instance)  {  	LLMatrix4 transformation = instance.mTransform; -	if (instance.mMeshID.isNull()) -	{ -		llerrs << "WTF?" << llendl; -	} - +	llassert(instance.mMeshID.notNull()); +	  	// check for reflection  	BOOL reflected = (transformation.determinant() < 0); @@ -3243,6 +3144,8 @@ bool LLImportMaterial::operator<(const LLImportMaterial &rhs) const  void LLMeshRepository::updateInventory(inventory_data data)  {  	LLMutexLock lock(mMeshMutex); +	dump_llsd_to_file(data.mPostData,make_dump_name("update_inventory_post_data_",dump_num)); +	dump_llsd_to_file(data.mResponse,make_dump_name("update_inventory_response_",dump_num));  	mInventoryQ.push(data);  } @@ -3400,15 +3303,18 @@ void LLPhysicsDecomp::setMeshData(LLCDMeshData& mesh)  	mesh.mNumTriangles = mCurRequest->mIndices.size()/3; -	LLCDResult ret = LLCD_OK; -	if (LLConvexDecomposition::getInstance() != NULL) +	if (mesh.mNumTriangles > 0 && mesh.mNumVertices > 2)  	{ -		ret  = LLConvexDecomposition::getInstance()->setMeshData(&mesh); -	} +		LLCDResult ret = LLCD_OK; +		if (LLConvexDecomposition::getInstance() != NULL) +		{ +			ret  = LLConvexDecomposition::getInstance()->setMeshData(&mesh); +		} -	if (ret) -	{ -		llerrs << "Convex Decomposition thread valid but could not set mesh data" << llendl; +		if (ret) +		{ +			llerrs << "Convex Decomposition thread valid but could not set mesh data" << llendl; +		}  	}  } @@ -3472,11 +3378,6 @@ void LLPhysicsDecomp::doDecomposition()  		{  			ret = LLConvexDecomposition::getInstance()->setParam(param->mName, value.asBoolean());  		} - -		if (ret) -		{ -			llerrs << "WTF?" << llendl; -		}  	}  	mCurRequest->setStatusMessage("Executing."); @@ -3771,6 +3672,81 @@ void LLPhysicsDecomp::run()  	mDone = true;  } +void LLPhysicsDecomp::Request::assignData(LLModel* mdl)  +{ +	if (!mdl) +	{ +		return ; +	} + +	U16 index_offset = 0; +	U16 tri[3] ; + +	mPositions.clear(); +	mIndices.clear(); +	mBBox[1] = LLVector3(F32_MIN, F32_MIN, F32_MIN) ; +	mBBox[0] = LLVector3(F32_MAX, F32_MAX, F32_MAX) ; +		 +	//queue up vertex positions and indices +	for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) +	{ +		const LLVolumeFace& face = mdl->getVolumeFace(i); +		if (mPositions.size() + face.mNumVertices > 65535) +		{ +			continue; +		} + +		for (U32 j = 0; j < face.mNumVertices; ++j) +		{ +			mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr())); +			for(U32 k = 0 ; k < 3 ; k++) +			{ +				mBBox[0].mV[k] = llmin(mBBox[0].mV[k], mPositions[j].mV[k]) ; +				mBBox[1].mV[k] = llmax(mBBox[1].mV[k], mPositions[j].mV[k]) ; +			} +		} + +		updateTriangleAreaThreshold() ; + +		for (U32 j = 0; j+2 < face.mNumIndices; j += 3) +		{ +			tri[0] = face.mIndices[j] + index_offset ; +			tri[1] = face.mIndices[j + 1] + index_offset ; +			tri[2] = face.mIndices[j + 2] + index_offset ; +				 +			if(isValidTriangle(tri[0], tri[1], tri[2])) +			{ +				mIndices.push_back(tri[0]); +				mIndices.push_back(tri[1]); +				mIndices.push_back(tri[2]); +			} +		} + +		index_offset += face.mNumVertices; +	} + +	return ; +} + +void LLPhysicsDecomp::Request::updateTriangleAreaThreshold()  +{ +	F32 range = mBBox[1].mV[0] - mBBox[0].mV[0] ; +	range = llmin(range, mBBox[1].mV[1] - mBBox[0].mV[1]) ; +	range = llmin(range, mBBox[1].mV[2] - mBBox[0].mV[2]) ; + +	mTriangleAreaThreshold = llmin(0.0002f, range * 0.000002f) ; +} + +//check if the triangle area is large enough to qualify for a valid triangle +bool LLPhysicsDecomp::Request::isValidTriangle(U16 idx1, U16 idx2, U16 idx3)  +{ +	LLVector3 a = mPositions[idx2] - mPositions[idx1] ; +	LLVector3 b = mPositions[idx3] - mPositions[idx1] ; +	F32 c = a * b ; + +	return ((a*a) * (b*b) - c * c) > mTriangleAreaThreshold ; +} +  void LLPhysicsDecomp::Request::setStatusMessage(const std::string& msg)  {  	mStatusMessage = msg; @@ -3868,3 +3844,27 @@ void LLMeshRepository::buildPhysicsMesh(LLModel::Decomposition& decomp)  		}  	}  } + + +bool LLMeshRepository::meshUploadEnabled() +{ +	LLViewerRegion *region = gAgent.getRegion(); +	if(gSavedSettings.getBOOL("MeshEnabled") &&  +	   LLViewerParcelMgr::getInstance()->allowAgentBuild() && +	   region) +	{ +		return region->meshUploadEnabled(); +	} +	return false; +} + +bool LLMeshRepository::meshRezEnabled() +{ +	LLViewerRegion *region = gAgent.getRegion(); +	if(gSavedSettings.getBOOL("MeshEnabled") &&  +	   region) +	{ +		return region->meshRezEnabled(); +	} +	return false; +} diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index f859e29c07..f237c3a60e 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -152,7 +152,7 @@ public:  		std::string mStatusMessage;  		std::vector<LLModel::PhysicsMesh> mHullMesh;  		LLModel::convex_hull_decomposition mHull; -		 +			  		//status message callback, called from decomposition thread  		virtual S32 statusCallback(const char* status, S32 p1, S32 p2) = 0; @@ -160,6 +160,17 @@ public:  		virtual void completed() = 0;  		virtual void setStatusMessage(const std::string& msg); + +		bool isValid() const {return mPositions.size() > 2 && mIndices.size() > 2 ;} + +	protected: +		//internal use +		LLVector3 mBBox[2] ; +		F32 mTriangleAreaThreshold ; + +		void assignData(LLModel* mdl) ; +		void updateTriangleAreaThreshold() ; +		bool isValidTriangle(U16 idx1, U16 idx2, U16 idx3) ;  	};  	LLCondition* mSignal; @@ -385,8 +396,6 @@ public:  	BOOL            mDiscarded ;  	LLHost			mHost; -	std::string		mUploadObjectAssetCapability; -	std::string		mNewInventoryCapability;  	std::string		mWholeModelFeeCapability;  	std::string		mWholeModelUploadURL; @@ -405,12 +414,10 @@ public:  	void uploadTexture(LLTextureUploadData& data);  	void doUploadTexture(LLTextureUploadData& data); -	void sendCostRequest(LLTextureUploadData& data);  	void priceResult(LLTextureUploadData& data, const LLSD& content);  	void onTextureUploaded(LLTextureUploadData& data);  	void uploadModel(LLMeshUploadData& data); -	void sendCostRequest(LLMeshUploadData& data);  	void doUploadModel(LLMeshUploadData& data);  	void onModelUploaded(LLMeshUploadData& data);  	void createObjects(LLMeshUploadData& data); @@ -424,7 +431,6 @@ public:  	BOOL isDiscarded();  	void doWholeModelUpload(); -	void doIterativeUpload();  	void wholeModelToLLSD(LLSD& dest, bool include_textures); @@ -467,13 +473,17 @@ public:  	static S32 getActualMeshLOD(LLSD& header, S32 lod);  	U32 calcResourceCost(LLSD& header);  	U32 getResourceCost(const LLUUID& mesh_params); -	const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id); +	const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj);  	LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id);  	void fetchPhysicsShape(const LLUUID& mesh_id);  	bool hasPhysicsShape(const LLUUID& mesh_id);  	void buildHull(const LLVolumeParams& params, S32 detail);  	void buildPhysicsMesh(LLModel::Decomposition& decomp); +	 +	bool meshUploadEnabled(); +	bool meshRezEnabled(); +	  	LLSD& getMeshHeader(const LLUUID& mesh_id); @@ -496,7 +506,8 @@ public:  	std::vector<LLMeshRepoThread::LODRequest> mPendingRequests;  	//list of mesh ids awaiting skin info -	std::set<LLUUID> mLoadingSkins; +	typedef std::map<LLUUID, std::set<LLUUID> > skin_load_map; +	skin_load_map mLoadingSkins;  	//list of mesh ids that need to send skin info fetch requests  	std::queue<LLUUID> mPendingSkinRequests; diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index b4d0ada196..52917ff20b 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -1740,26 +1740,11 @@ void LLPanelObject::refresh()  		mRootObject = NULL;  	} -	bool enable_mesh = gSavedSettings.getBOOL("MeshEnabled") &&  -					   gAgent.getRegion() && -					   !gAgent.getRegion()->getCapability("GetMesh").empty() && -					   !gAgent.getRegion()->getCapability("ObjectAdd").empty(); -  	F32 max_scale = get_default_max_prim_scale(LLPickInfo::isFlora(mObject));  	getChild<LLSpinCtrl>("Scale X")->setMaxValue(max_scale);  	getChild<LLSpinCtrl>("Scale Y")->setMaxValue(max_scale);  	getChild<LLSpinCtrl>("Scale Z")->setMaxValue(max_scale); - -	BOOL found = mCtrlSculptType->itemExists("Mesh"); -	if (enable_mesh && !found) -	{ -		mCtrlSculptType->add("Mesh"); -	} -	else if (!enable_mesh && found) -	{ -		mCtrlSculptType->remove("Mesh"); -	}  } diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 7839cdd811..bb87601d20 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -530,17 +530,24 @@ void LLPanelVolume::refresh()  	getChildView("Light Ambiance")->setVisible( visible);  	getChildView("light texture control")->setVisible( visible); -	bool enable_mesh = gSavedSettings.getBOOL("MeshEnabled") &&  -					   gAgent.getRegion() && -					   !gAgent.getRegion()->getCapability("GetMesh").empty() && -					   !gAgent.getRegion()->getCapability("ObjectAdd").empty(); +	bool enable_mesh = false; +	LLSD sim_features; +	LLViewerRegion *region = gAgent.getRegion(); +	if(region) +	{ +		LLSD sim_features; +		region->getSimulatorFeatures(sim_features);		  +		enable_mesh = sim_features.has("PhysicsShapeTypes"); +	}  	getChildView("label physicsshapetype")->setVisible(enable_mesh);  	getChildView("Physics Shape Type Combo Ctrl")->setVisible(enable_mesh);  	getChildView("Physics Gravity")->setVisible(enable_mesh);  	getChildView("Physics Friction")->setVisible(enable_mesh);  	getChildView("Physics Density")->setVisible(enable_mesh);  	getChildView("Physics Restitution")->setVisible(enable_mesh); +	 +    /* TODO: add/remove individual physics shape types as per the PhysicsShapeTypes simulator features */  } diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index fa329eb0ae..a5b91729e8 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -35,6 +35,7 @@  #include "llvolumeoctree.h"  #include "llviewercamera.h"  #include "llface.h" +#include "llfloatertools.h"  #include "llviewercontrol.h"  #include "llviewerregion.h"  #include "llcamera.h" @@ -69,6 +70,7 @@ U32 LLSpatialGroup::sNodeCount = 0;  std::set<GLuint> LLSpatialGroup::sPendingQueries; +U32 gOctreeMaxCapacity;  BOOL LLSpatialGroup::sNoDelete = FALSE; @@ -630,7 +632,7 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate)  	if (mOctreeNode->isInside(drawablep->getPositionGroup()) &&   		(mOctreeNode->contains(drawablep) ||  		 (drawablep->getBinRadius() > mOctreeNode->getSize()[0] && -				parent && parent->getElementCount() >= LL_OCTREE_MAX_CAPACITY))) +				parent && parent->getElementCount() >= gOctreeMaxCapacity)))  	{  		unbound();  		setState(OBJECT_DIRTY); @@ -689,17 +691,8 @@ static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt");  void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)  { -	/*if (!gPipeline.hasRenderType(mDrawableType)) -	{ -		return; -	}*/ -  	if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY))  	{ -		/*if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && mRenderByGroup) -		{ -			llerrs << "WTF?" << llendl; -		}*/  		return;  	} @@ -961,21 +954,15 @@ void LLSpatialGroup::setState(U32 state)  {   	mState |= state;  -	if (state > LLSpatialGroup::STATE_MASK) -	{ -		llerrs << "WTF?" << llendl; -	} +	llassert(state <= LLSpatialGroup::STATE_MASK);  }	  void LLSpatialGroup::setState(U32 state, S32 mode)   {  	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); -	if (state > LLSpatialGroup::STATE_MASK) -	{ -		llerrs << "WTF?" << llendl; -	} - +	llassert(state <= LLSpatialGroup::STATE_MASK); +	  	if (mode > STATE_MODE_SINGLE)  	{  		if (mode == STATE_MODE_DIFF) @@ -1021,20 +1008,14 @@ public:  void LLSpatialGroup::clearState(U32 state)  { -	if (state > LLSpatialGroup::STATE_MASK) -	{ -		llerrs << "WTF?" << llendl; -	} +	llassert(state <= LLSpatialGroup::STATE_MASK);  	mState &= ~state;   }  void LLSpatialGroup::clearState(U32 state, S32 mode)  { -	if (state > LLSpatialGroup::STATE_MASK) -	{ -		llerrs << "WTF?" << llendl; -	} +	llassert(state <= LLSpatialGroup::STATE_MASK);  	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -1059,10 +1040,7 @@ void LLSpatialGroup::clearState(U32 state, S32 mode)  BOOL LLSpatialGroup::isState(U32 state) const  {  -	if (state > LLSpatialGroup::STATE_MASK) -	{ -		llerrs << "WTF?" << llendl; -	} +	llassert(state <= LLSpatialGroup::STATE_MASK);  	return mState & state ? TRUE : FALSE;   } @@ -1250,7 +1228,8 @@ void LLSpatialGroup::updateDistance(LLCamera &camera)  {  	if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)  	{ -		llerrs << "WTF?" << llendl; +		llwarns << "Attempted to update distance for camera other than world camera!" << llendl; +		return;  	}  #if !LL_RELEASE_FOR_DOWNLOAD @@ -2064,11 +2043,8 @@ public:  	virtual void processGroup(LLSpatialGroup* group)  	{ -		if (group->isState(LLSpatialGroup::DIRTY) || group->getData().empty()) -		{ -			llerrs << "WTF?" << llendl; -		} - +		llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->getData().empty()) +		  		if (mRes < 2)  		{  			if (mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]) > 0) @@ -2541,7 +2517,7 @@ void renderOctree(LLSpatialGroup* group)  	//coded by buffer usage and activity  	gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);  	LLVector4 col; -	if (group->mBuilt > 0.f) +	/*if (group->mBuilt > 0.f)  	{  		group->mBuilt -= 2.f * gFrameIntervalSeconds;  		if (group->mBufferUsage == GL_STATIC_DRAW_ARB) @@ -2610,7 +2586,7 @@ void renderOctree(LLSpatialGroup* group)  			gGL.color4f(1,1,1,1);  		}  	} -	else +	else*/  	{  		if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->getData().empty()   			&& group->mSpatialPartition->mRenderByGroup) @@ -2630,33 +2606,24 @@ void renderOctree(LLSpatialGroup* group)  	size.mul(1.01f);  	size.add(fudge); -	{ -		LLGLDepthTest depth(GL_TRUE, GL_FALSE); -		drawBox(group->mObjectBounds[0], fudge); -	} +	//{ +	//	LLGLDepthTest depth(GL_TRUE, GL_FALSE); +	//	drawBox(group->mObjectBounds[0], fudge); +	//}  	gGL.setSceneBlendType(LLRender::BT_ALPHA); -	if (group->mBuilt <= 0.f) +	//if (group->mBuilt <= 0.f)  	{  		//draw opaque outline -		gGL.color4f(col.mV[0], col.mV[1], col.mV[2], 1.f); -		drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]); +		//gGL.color4f(col.mV[0], col.mV[1], col.mV[2], 1.f); +		//drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]); -		if (group->mOctreeNode->isLeaf()) -		{ -			gGL.color4f(1,1,1,1); -		} -		else -		{ -			gGL.color4f(0,1,1,1); -		} -						 +		gGL.color4f(0,1,1,1);  		drawBoxOutline(group->mBounds[0],group->mBounds[1]); - - +		  		//draw bounding box for draw info -		if (group->mSpatialPartition->mRenderByGroup) +		/*if (group->mSpatialPartition->mRenderByGroup)  		{  			gGL.color4f(1.0f, 0.75f, 0.25f, 0.6f);  			for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) @@ -2673,7 +2640,7 @@ void renderOctree(LLSpatialGroup* group)  					drawBoxOutline(center, size);  				}  			} -		} +		}*/  	}  //	LLSpatialGroup::OctreeNode* node = group->mOctreeNode; @@ -2716,7 +2683,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)  			gGL.color4f(0.f, 0.75f, 0.f, 0.5f);  			pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);  		} -		else if (camera && group->mOcclusionVerts.notNull()) +		/*else if (camera && group->mOcclusionVerts.notNull())  		{  			LLVertexBuffer::unbind();  			group->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX); @@ -2728,7 +2695,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)  			glColor4f(1.0f, 1.f, 1.f, 1.0f);  			group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0]));  			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -		} +		}*/  	}  } @@ -3002,13 +2969,6 @@ void render_hull(LLModel::PhysicsMesh& mesh, const LLColor4& color, const LLColo  void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)  { -	if (volume->isSelected()) -	{ -		LLVector3 construct_me(5,5,5); -		construct_me.normalize(); -	} - -	  	U8 physics_type = volume->getPhysicsShapeType();  	if (physics_type == LLViewerObject::PHYSICS_SHAPE_NONE || volume->isFlexible()) @@ -3473,6 +3433,8 @@ void renderTextureAnim(LLDrawInfo* params)  void renderBatchSize(LLDrawInfo* params)  { +	LLGLEnable offset(GL_POLYGON_OFFSET_FILL); +	glPolygonOffset(-1.f, 1.f);  	glColor3ubv((GLubyte*) &(params->mDebugColor));  	pushVerts(params, LLVertexBuffer::MAP_VERTEX);  } @@ -3910,6 +3872,28 @@ public:  				renderAgentTarget(avatar);  			} +			if (gDebugGL) +			{ +				for (U32 i = 0; i < drawable->getNumFaces(); ++i) +				{ +					LLFace* facep = drawable->getFace(i); +					U8 index = facep->getTextureIndex(); +					if (facep->mDrawInfo) +					{ +						if (index < 255) +						{ +							if (facep->mDrawInfo->mTextureList.size() <= index) +							{ +								llerrs << "Face texture index out of bounds." << llendl; +							} +							else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture()) +							{ +								llerrs << "Face texture index incorrect." << llendl; +							} +						} +					} +				} +			}  		}  		for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) @@ -4282,7 +4266,29 @@ public:  			if (vobj)  			{  				LLVector3 intersection; -				if (vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal)) +				bool skip_check = false; +				if (vobj->isAvatar()) +				{ +					LLVOAvatar* avatar = (LLVOAvatar*) vobj; +					if (avatar->isSelf() && LLFloater::isVisible(gFloaterTools)) +					{ +						LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal); +						if (hit) +						{ +							mEnd = intersection; +							if (mIntersection) +							{ +								*mIntersection = intersection; +							} +							 +							mHit = hit->mDrawable; +							skip_check = true; +						} + +					} +				} + +				if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal))  				{  					mEnd = intersection;  // shorten ray so we only find CLOSER hits  					if (mIntersection) diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 0d9cad914a..db8a0c2992 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -91,6 +91,8 @@ public:  	LLPointer<LLVertexBuffer> mVertexBuffer;  	LLPointer<LLViewerTexture>     mTexture; +	std::vector<LLPointer<LLViewerTexture> > mTextureList; +  	LLColor4U mGlowColor;  	S32 mDebugColor;  	const LLMatrix4* mTextureMatrix; @@ -207,7 +209,7 @@ public:  	typedef std::vector<LLPointer<LLDrawInfo> > drawmap_elem_t;   	typedef std::map<U32, drawmap_elem_t > draw_map_t;	  	typedef std::vector<LLPointer<LLVertexBuffer> > buffer_list_t; -	typedef std::map<LLPointer<LLViewerTexture>, buffer_list_t> buffer_texture_map_t; +	typedef std::map<LLFace*, buffer_list_t> buffer_texture_map_t;  	typedef std::map<U32, buffer_texture_map_t> buffer_map_t;  	typedef LLOctreeListener<LLDrawable>	BaseType; @@ -399,7 +401,7 @@ protected:  public:  	bridge_list_t mBridgeList; -	buffer_map_t mBufferMap; //used by volume buffers to store unique buffers per texture +	buffer_map_t mBufferMap; //used by volume buffers to attempt to reuse vertex buffers  	F32 mBuilt;  	OctreeNode* mOctreeNode; @@ -684,7 +686,7 @@ class LLVolumeGeometryManager: public LLGeometryManager  	virtual void rebuildGeom(LLSpatialGroup* group);  	virtual void rebuildMesh(LLSpatialGroup* group);  	virtual void getGeometry(LLSpatialGroup* group); -	void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE); +	void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE);  	void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);  }; diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 379bbe614d..87ca80260f 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -57,6 +57,7 @@  #include "llworld.h"  #include "pipeline.h"  #include "llviewerjoystick.h" +#include "llviewerobjectlist.h"  #include "llviewerparcelmgr.h"  #include "llparcel.h"  #include "llkeyboard.h" @@ -183,6 +184,21 @@ static bool handleReleaseGLBufferChanged(const LLSD& newvalue)  	return true;  } +static bool handleFSAASamplesChanged(const LLSD& newvalue) +{ +	if (gPipeline.isInit()) +	{ +		gPipeline.releaseGLBuffers(); +		gPipeline.createGLBuffers(); + +		if (LLPipeline::sRenderDeferred) +		{ +			LLViewerShaderMgr::instance()->setShaders(); +		} +	} +	return true; +} +  static bool handleAnisotropicChanged(const LLSD& newvalue)  {  	LLImageGL::sGlobalUseAnisotropic = newvalue.asBoolean(); @@ -357,6 +373,16 @@ static bool handleResetVertexBuffersChanged(const LLSD&)  	return true;  } +static bool handleRepartition(const LLSD&) +{ +	if (gPipeline.isInit()) +	{ +		gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); +		gObjectList.repartitionObjects(); +	} +	return true; +} +  static bool handleRenderDynamicLODChanged(const LLSD& newvalue)  {  	LLPipeline::sDynamicLOD = newvalue.asBoolean(); @@ -560,6 +586,12 @@ void settings_setup_listeners()  	gSavedSettings.getControl("FirstPersonAvatarVisible")->getSignal()->connect(boost::bind(&handleRenderAvatarMouselookChanged, _2));  	gSavedSettings.getControl("RenderFarClip")->getSignal()->connect(boost::bind(&handleRenderFarClipChanged, _2));  	gSavedSettings.getControl("RenderTerrainDetail")->getSignal()->connect(boost::bind(&handleTerrainDetailChanged, _2)); +	gSavedSettings.getControl("OctreeStaticObjectSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); +	gSavedSettings.getControl("OctreeDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); +	gSavedSettings.getControl("OctreeMaxNodeCapacity")->getSignal()->connect(boost::bind(&handleRepartition, _2)); +	gSavedSettings.getControl("OctreeAlphaDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); +	gSavedSettings.getControl("OctreeAttachmentSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); +	gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));  	gSavedSettings.getControl("RenderUseTriStrips")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));  	gSavedSettings.getControl("RenderAnimateTrees")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));  	gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); @@ -568,7 +600,7 @@ void settings_setup_listeners()  	gSavedSettings.getControl("RenderSpecularResX")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));  	gSavedSettings.getControl("RenderSpecularResY")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));  	gSavedSettings.getControl("RenderSpecularExponent")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); -	gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); +	gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleFSAASamplesChanged, _2));  	gSavedSettings.getControl("RenderAnisotropic")->getSignal()->connect(boost::bind(&handleAnisotropicChanged, _2));  	gSavedSettings.getControl("RenderShadowResolutionScale")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));  	gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index e41773d273..f725f0fe86 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -582,6 +582,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			LLMemType mt_ug(LLMemType::MTYPE_DISPLAY_UPDATE_GEOM);  			const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time  			gPipeline.createObjects(max_geom_update_time); +			gPipeline.processPartitionQ();  			gPipeline.updateGeom(max_geom_update_time);  			stop_glerror();  		} @@ -836,7 +837,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)  			{  				gPipeline.mDeferredScreen.bindTarget(); -				glClearColor(0,0,0,0); +				glClearColor(1,0,1,1);  				gPipeline.mDeferredScreen.clear();  			}  			else @@ -995,8 +996,7 @@ void render_hud_attachments()  		S32 use_occlusion = LLPipeline::sUseOcclusion;  		LLPipeline::sUseOcclusion = 0; -		LLPipeline::sDisableShaders = TRUE; -		 +				  		//cull, sort, and render hud objects  		static LLCullResult result;  		LLSpatialGroup::sNoDelete = TRUE; @@ -1036,7 +1036,6 @@ void render_hud_attachments()  			gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);  		}  		LLPipeline::sUseOcclusion = use_occlusion; -		LLPipeline::sDisableShaders = FALSE;  	}  	glMatrixMode(GL_PROJECTION);  	glPopMatrix(); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 37640ad0d4..b9293b3b31 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -107,9 +107,7 @@ class LLMeshUploadVisible : public view_listener_t  {  	bool handleEvent(const LLSD& userdata)  	{ -		return gSavedSettings.getBOOL("MeshEnabled") &&  -			   LLViewerParcelMgr::getInstance()->allowAgentBuild() &&  -			   !gAgent.getRegion()->getCapability("ObjectAdd").empty(); +		return gMeshRepo.meshUploadEnabled();  	}  }; @@ -1203,78 +1201,6 @@ void upload_new_resource(  	}  } -BOOL upload_new_variable_price_resource( -	const LLTransactionID &tid,  -	LLAssetType::EType asset_type, -	std::string name, -	std::string desc,  -	LLFolderType::EType destination_folder_type, -	LLInventoryType::EType inv_type, -	U32 next_owner_perms, -	U32 group_perms, -	U32 everyone_perms, -	const std::string& display_name, -	const LLSD& asset_resources) -{ -	LLAssetID uuid =  -		upload_new_resource_prep( -			tid, -			asset_type, -			inv_type, -			name, -			display_name, -			desc); - -	llinfos << "*** Uploading: " << llendl; -	llinfos << "Type: " << LLAssetType::lookup(asset_type) << llendl; -	llinfos << "UUID: " << uuid << llendl; -	llinfos << "Name: " << name << llendl; -	llinfos << "Desc: " << desc << llendl; -	lldebugs << "Folder: " -		<< gInventory.findCategoryUUIDForType((destination_folder_type == LLFolderType::FT_NONE) ? (LLFolderType::EType)asset_type : destination_folder_type) << llendl; -	lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl; - -	std::string url = gAgent.getRegion()->getCapability( -		"NewFileAgentInventoryVariablePrice"); - -	if ( !url.empty() ) -	{ -		lldebugs -			<< "New Agent Inventory variable price upload" << llendl; -		 -		// Each of the two capabilities has similar data, so -		// let's reuse that code - -		LLSD body; - -		body = generate_new_resource_upload_capability_body( -			asset_type, -			name, -			desc, -			destination_folder_type, -			inv_type, -			next_owner_perms, -			group_perms, -			everyone_perms); - -		body["asset_resources"] = asset_resources; - -		LLHTTPClient::post( -			url, -			body, -			new LLNewAgentInventoryVariablePriceResponder( -				uuid, -				asset_type, -				body)); - -		return TRUE; -	} -	else -	{ -		return FALSE; -	} -} -  LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid)  {  	if ( gDisconnected ) diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h index 1597821504..3136358b83 100644 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -68,23 +68,6 @@ void upload_new_resource(  	S32 expected_upload_cost,  	void *userdata); -// TODO* : Move all uploads to use this new function -// since at some point, that upload path will be deprecated and no longer -// used - -// We make a new function here to ensure that previous code is not broken -BOOL upload_new_variable_price_resource( -	const LLTransactionID& tid,  -	LLAssetType::EType type, -	std::string name, -	std::string desc,  -	LLFolderType::EType destination_folder_type, -	LLInventoryType::EType inv_type, -	U32 next_owner_perms, -	U32 group_perms, -	U32 everyone_perms, -	const std::string& display_name, -	const LLSD& asset_resources);  LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid);  void increase_new_upload_stats(LLAssetType::EType asset_type); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 01a5cb18db..7ab335314a 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -96,7 +96,6 @@  #include "llviewerwindow.h"  #include "llvlmanager.h"  #include "llvoavatarself.h" -#include "llvotextbubble.h"  #include "llworld.h"  #include "pipeline.h"  #include "llfloaterworldmap.h" @@ -4228,15 +4227,8 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)  				// Display green bubble on kill  				if ( gShowObjectUpdates )  				{ -					LLViewerObject* newobject; -					newobject = gObjectList.createObjectViewer(LL_PCODE_LEGACY_TEXT_BUBBLE, objectp->getRegion()); - -					LLVOTextBubble* bubble = (LLVOTextBubble*) newobject; - -					bubble->mColor.setVec(0.f, 1.f, 0.f, 1.f); -					bubble->setScale( 2.0f * bubble->getScale() ); -					bubble->setPositionGlobal(objectp->getPositionGlobal()); -					gPipeline.addObject(bubble); +					LLColor4 color(0.f,1.f,0.f,1.f); +					gPipeline.addDebugBlip(objectp->getPositionAgent(), color);  				}  				// Do the kill diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index e7878d8adf..be9ff872c0 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -89,7 +89,6 @@  #include "llvopartgroup.h"  #include "llvosky.h"  #include "llvosurfacepatch.h" -#include "llvotextbubble.h"  #include "llvotree.h"  #include "llvovolume.h"  #include "llvowater.h" @@ -168,8 +167,6 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco  // 	  llwarns << "Creating new tree!" << llendl;  // 	  res = new LLVOTree(id, pcode, regionp); break;  	  res = NULL; break; -	case LL_PCODE_LEGACY_TEXT_BUBBLE: -	  res = new LLVOTextBubble(id, pcode, regionp); break;  	case LL_VO_CLOUDS:  	  res = new LLVOClouds(id, pcode, regionp); break;  	case LL_VO_SURFACE_PATCH: @@ -1894,7 +1891,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  	//  	// -	// WTF?   If we're going to skip this message, why are we  +	// If we're going to skip this message, why are we   	// doing all the parenting, etc above?  	U32 packet_id = mesgsys->getCurrentRecvPacketID();   	if (packet_id < mLatestRecvPacketID &&  @@ -1973,23 +1970,16 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  	if ( gShowObjectUpdates )  	{ -		if (!((mPrimitiveCode == LL_PCODE_LEGACY_AVATAR) && (((LLVOAvatar *) this)->isSelf())) -			&& mRegionp) +		LLColor4 color; +		if (update_type == OUT_TERSE_IMPROVED)  		{ -			LLViewerObject* object = gObjectList.createObjectViewer(LL_PCODE_LEGACY_TEXT_BUBBLE, mRegionp); -			LLVOTextBubble* bubble = (LLVOTextBubble*) object; - -			if (update_type == OUT_TERSE_IMPROVED) -			{ -				bubble->mColor.setVec(0.f, 0.f, 1.f, 1.f); -			} -			else -			{ -				bubble->mColor.setVec(1.f, 0.f, 0.f, 1.f); -			} -			object->setPositionGlobal(getPositionGlobal()); -			gPipeline.addObject(object); +			color.setVec(0.f, 0.f, 1.f, 1.f); +		} +		else +		{ +			color.setVec(1.f, 0.f, 0.f, 1.f);  		} +		gPipeline.addDebugBlip(getPositionAgent(), color);  	}  	if ((0.0f == vel_mag_sq) &&  diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 007b3416f1..45c6777ae8 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1418,12 +1418,12 @@ void LLViewerObjectList::onObjectCostFetchFailure(const LLUUID& object_id)  	mPendingObjectCost.erase(object_id);  } -void LLViewerObjectList::updateQuotaCost( const LLUUID& objectId, const SelectionQuota& quota  ) +void LLViewerObjectList::updateQuota( const LLUUID& objectId, const SelectionQuota& quota  )  {  	LLViewerObject* pVO = findObject( objectId );  	if ( pVO )  	{ -		//pVO->updateQuota( quota ); +		pVO->updateQuota( quota );  	}  } @@ -1497,6 +1497,24 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset)  	LLWorld::getInstance()->shiftRegions(offset);  } +void LLViewerObjectList::repartitionObjects() +{ +	for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) +	{ +		LLViewerObject* objectp = *iter; +		if (!objectp->isDead()) +		{ +			LLDrawable* drawable = objectp->mDrawable; +			if (drawable && !drawable->isDead()) +			{ +				drawable->updateBinRadius(); +				drawable->updateSpatialExtents(); +				drawable->movePartition(); +			} +		} +	} +} +  //debug code  bool LLViewerObjectList::hasMapObjectInRegion(LLViewerRegion* regionp)   { diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 8e211eaf73..9d1b5cb56f 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -102,9 +102,10 @@ public:  									F32 restitution,  									F32 gravity_multiplier); -	void updateQuotaCost( const LLUUID& objectId, const SelectionQuota& costs ); +	void updateQuota( const LLUUID& objectId, const SelectionQuota& costs );  	void shiftObjects(const LLVector3 &offset); +	void repartitionObjects();  	bool hasMapObjectInRegion(LLViewerRegion* regionp) ;  	void clearAllMapObjectsInRegion(LLViewerRegion* regionp) ; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 590c82856d..002e0567e4 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -69,6 +69,7 @@  #include "llspatialpartition.h"  #include "stringize.h"  #include "llviewercontrol.h" +#include "llsdserialize.h"  #ifdef LL_WINDOWS  	#pragma warning(disable:4355) @@ -1140,6 +1141,20 @@ void LLViewerRegion::getInfo(LLSD& info)  	info["Region"]["Handle"]["y"] = (LLSD::Integer)y;  } +void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features) +{ +	sim_features = mSimulatorFeatures; +} + +void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) +{ +	std::stringstream str; +	 +	LLSDSerialize::toPrettyXML(sim_features, str); +	llinfos << str.str() << llendl; +	mSimulatorFeatures = sim_features; +} +  LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp)  {  	U32 local_id = objectp->getLocalID(); @@ -1480,6 +1495,8 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	LLSD capabilityNames = LLSD::emptyArray(); +	capabilityNames.append("AccountingParcel"); +	capabilityNames.append("AccountingSelection");  	capabilityNames.append("AttachmentResources");  	capabilityNames.append("AvatarPickerSearch");  	capabilityNames.append("ChatSessionRequest"); @@ -1509,8 +1526,6 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	capabilityNames.append("MapLayer");  	capabilityNames.append("MapLayerGod");  	capabilityNames.append("NewFileAgentInventory"); -	capabilityNames.append("NewFileAgentInventoryVariablePrice"); -	capabilityNames.append("ObjectAdd");  	capabilityNames.append("ParcelPropertiesUpdate");  	capabilityNames.append("ParcelMediaURLFilterList");  	capabilityNames.append("ParcelNavigateMedia"); @@ -1541,7 +1556,6 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	capabilityNames.append("UpdateNotecardTaskInventory");  	capabilityNames.append("UpdateScriptTask");  	capabilityNames.append("UploadBakedTexture"); -	capabilityNames.append("UploadObjectAsset");  	capabilityNames.append("ViewerMetrics");  	capabilityNames.append("ViewerStartAuction");  	capabilityNames.append("ViewerStats"); @@ -1559,6 +1573,42 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	LLHTTPClient::post(url, capabilityNames, mImpl->mHttpResponderPtr);  } +class SimulatorFeaturesReceived : public LLHTTPClient::Responder +{ +	LOG_CLASS(SimulatorFeaturesReceived); +public: +    SimulatorFeaturesReceived(LLViewerRegion* region) +	: mRegion(region) +    { } +	 +	 +    void error(U32 statusNum, const std::string& reason) +    { +		LL_WARNS2("AppInit", "SimulatorFeatures") << statusNum << ": " << reason << LL_ENDL; +    } +	 +    void result(const LLSD& content) +    { +		if(!mRegion) //region is removed or responder is not created. +		{ +			return ; +		} +		 +		mRegion->setSimulatorFeatures(content); +	} +	 +    static boost::intrusive_ptr<SimulatorFeaturesReceived> build( +																 LLViewerRegion* region) +    { +		return boost::intrusive_ptr<SimulatorFeaturesReceived>( +															   new SimulatorFeaturesReceived(region)); +    } +	 +private: +	LLViewerRegion* mRegion; +}; + +  void LLViewerRegion::setCapability(const std::string& name, const std::string& url)  {  	if(name == "EventQueueGet") @@ -1571,6 +1621,11 @@ void LLViewerRegion::setCapability(const std::string& name, const std::string& u  	{  		LLHTTPSender::setSender(mImpl->mHost, new LLCapHTTPSender(url));  	} +	else if (name == "SimulatorFeatures") +	{ +		// kick off a request for simulator features +		LLHTTPClient::get(url, new SimulatorFeaturesReceived(this)); +	}  	else  	{  		mImpl->mCapabilities[name] = url; @@ -1664,3 +1719,16 @@ std::string LLViewerRegion::getDescription() const      return stringize(*this);  } +bool LLViewerRegion::meshUploadEnabled() const +{ +	return (mSimulatorFeatures.has("MeshUploadEnabled") && +		mSimulatorFeatures["MeshUploadEnabled"].asBoolean()); +} + +bool LLViewerRegion::meshRezEnabled() const +{ +	return (mSimulatorFeatures.has("MeshRezEnabled") && +				mSimulatorFeatures["MeshRezEnabled"].asBoolean()); +} + + diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index a6e5c47b86..3811b989e7 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -276,6 +276,11 @@ public:  	void getInfo(LLSD& info); +	bool meshRezEnabled() const; +	bool meshUploadEnabled() const; + +	void getSimulatorFeatures(LLSD& info);	 +	void setSimulatorFeatures(const LLSD& info);  	typedef enum  	{ @@ -401,6 +406,8 @@ private:  	bool	mCapabilitiesReceived;  	BOOL mReleaseNotesRequested; +	 +	LLSD mSimulatorFeatures;  };  inline BOOL LLViewerRegion::getAllowDamage() const diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 3e85802ba6..e3ed2d0649 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -66,12 +66,20 @@ LLGLSLShader		gObjectSimpleProgram;  LLGLSLShader		gObjectSimpleWaterProgram;  LLGLSLShader		gObjectFullbrightProgram;  LLGLSLShader		gObjectFullbrightWaterProgram; -  LLGLSLShader		gObjectFullbrightShinyProgram;  LLGLSLShader		gObjectFullbrightShinyWaterProgram;  LLGLSLShader		gObjectShinyProgram;  LLGLSLShader		gObjectShinyWaterProgram; +LLGLSLShader		gObjectSimpleNonIndexedProgram; +LLGLSLShader		gObjectSimpleNonIndexedWaterProgram; +LLGLSLShader		gObjectFullbrightNonIndexedProgram; +LLGLSLShader		gObjectFullbrightNonIndexedWaterProgram; +LLGLSLShader		gObjectFullbrightShinyNonIndexedProgram; +LLGLSLShader		gObjectFullbrightShinyNonIndexedWaterProgram; +LLGLSLShader		gObjectShinyNonIndexedProgram; +LLGLSLShader		gObjectShinyNonIndexedWaterProgram; +  //object hardware skinning shaders  LLGLSLShader		gSkinnedObjectSimpleProgram;  LLGLSLShader		gSkinnedObjectFullbrightProgram; @@ -113,6 +121,7 @@ LLGLSLShader			gDeferredImpostorProgram;  LLGLSLShader			gDeferredEdgeProgram;  LLGLSLShader			gDeferredWaterProgram;  LLGLSLShader			gDeferredDiffuseProgram; +LLGLSLShader			gDeferredNonIndexedDiffuseProgram;  LLGLSLShader			gDeferredSkinnedDiffuseProgram;  LLGLSLShader			gDeferredSkinnedBumpProgram;  LLGLSLShader			gDeferredSkinnedAlphaProgram; @@ -132,13 +141,16 @@ LLGLSLShader			gDeferredShadowProgram;  LLGLSLShader			gDeferredAvatarShadowProgram;  LLGLSLShader			gDeferredAttachmentShadowProgram;  LLGLSLShader			gDeferredAlphaProgram; +LLGLSLShader			gDeferredAvatarEyesProgram;  LLGLSLShader			gDeferredFullbrightProgram;  LLGLSLShader			gDeferredGIProgram;  LLGLSLShader			gDeferredGIFinalProgram;  LLGLSLShader			gDeferredPostGIProgram;  LLGLSLShader			gDeferredPostProgram;  LLGLSLShader			gDeferredPostNoDoFProgram; - +LLGLSLShader			gDeferredWLSkyProgram; +LLGLSLShader			gDeferredWLCloudProgram; +LLGLSLShader			gDeferredStarProgram;  LLGLSLShader			gLuminanceGatherProgram; @@ -160,6 +172,10 @@ LLViewerShaderMgr::LLViewerShaderMgr() :  	mShaderList.push_back(&gObjectFullbrightProgram);  	mShaderList.push_back(&gObjectFullbrightShinyProgram);  	mShaderList.push_back(&gObjectFullbrightShinyWaterProgram); +	mShaderList.push_back(&gObjectSimpleNonIndexedProgram); +	mShaderList.push_back(&gObjectFullbrightNonIndexedProgram); +	mShaderList.push_back(&gObjectFullbrightShinyNonIndexedProgram); +	mShaderList.push_back(&gObjectFullbrightShinyNonIndexedWaterProgram);  	mShaderList.push_back(&gSkinnedObjectSimpleProgram);  	mShaderList.push_back(&gSkinnedObjectFullbrightProgram);  	mShaderList.push_back(&gSkinnedObjectFullbrightShinyProgram); @@ -183,6 +199,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() :  	mShaderList.push_back(&gDeferredAlphaProgram);  	mShaderList.push_back(&gDeferredSkinnedAlphaProgram);  	mShaderList.push_back(&gDeferredFullbrightProgram); +	mShaderList.push_back(&gDeferredAvatarEyesProgram);  	mShaderList.push_back(&gDeferredPostGIProgram);  	mShaderList.push_back(&gDeferredEdgeProgram);  	mShaderList.push_back(&gDeferredPostProgram); @@ -190,6 +207,9 @@ LLViewerShaderMgr::LLViewerShaderMgr() :  	mShaderList.push_back(&gDeferredGIFinalProgram);  	mShaderList.push_back(&gDeferredWaterProgram);  	mShaderList.push_back(&gDeferredAvatarAlphaProgram); +	mShaderList.push_back(&gDeferredWLSkyProgram); +	mShaderList.push_back(&gDeferredWLCloudProgram); +	mShaderList.push_back(&gDeferredStarProgram);  }  LLViewerShaderMgr::~LLViewerShaderMgr() @@ -347,6 +367,10 @@ void LLViewerShaderMgr::setShaders()  		return;  	} +	//setup preprocessor definitions +	LLShaderMgr::instance()->mDefinitions["samples"] = llformat("%d", gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples"))); +	LLShaderMgr::instance()->mDefinitions["NUM_TEX_UNITS"] = llformat("%d", gGLManager.mNumTextureImageUnits); +  	reentrance = true;  	// Make sure the compiled shader map is cleared before we recompile shaders. @@ -577,6 +601,16 @@ void LLViewerShaderMgr::unloadShaders()  	gObjectFullbrightShinyWaterProgram.unload();  	gObjectShinyWaterProgram.unload(); +	gObjectSimpleNonIndexedProgram.unload(); +	gObjectSimpleNonIndexedWaterProgram.unload(); +	gObjectFullbrightNonIndexedProgram.unload(); +	gObjectFullbrightNonIndexedWaterProgram.unload(); + +	gObjectShinyNonIndexedProgram.unload(); +	gObjectFullbrightShinyNonIndexedProgram.unload(); +	gObjectFullbrightShinyNonIndexedWaterProgram.unload(); +	gObjectShinyNonIndexedWaterProgram.unload(); +  	gSkinnedObjectSimpleProgram.unload();  	gSkinnedObjectFullbrightProgram.unload();  	gSkinnedObjectFullbrightShinyProgram.unload(); @@ -607,6 +641,7 @@ void LLViewerShaderMgr::unloadShaders()  	gPostNightVisionProgram.unload();  	gDeferredDiffuseProgram.unload(); +	gDeferredNonIndexedDiffuseProgram.unload();  	gDeferredSkinnedDiffuseProgram.unload();  	gDeferredSkinnedBumpProgram.unload();  	gDeferredSkinnedAlphaProgram.unload(); @@ -685,24 +720,35 @@ BOOL LLViewerShaderMgr::loadBasicShaders()  	shaders.clear();  	shaders.reserve(13); -	shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl",		mVertexShaderLevel[SHADER_WINDLIGHT] ) ); -	shaders.push_back( make_pair( "windlight/gammaF.glsl",					mVertexShaderLevel[SHADER_WINDLIGHT]) ); -	shaders.push_back( make_pair( "windlight/atmosphericsF.glsl",			mVertexShaderLevel[SHADER_WINDLIGHT] ) ); -	shaders.push_back( make_pair( "windlight/transportF.glsl",				mVertexShaderLevel[SHADER_WINDLIGHT] ) );	 -	shaders.push_back( make_pair( "environment/waterFogF.glsl",				mVertexShaderLevel[SHADER_WATER] ) ); -	shaders.push_back( make_pair( "lighting/lightF.glsl",					mVertexShaderLevel[SHADER_LIGHTING] ) ); -	shaders.push_back( make_pair( "lighting/lightFullbrightF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) ); -	shaders.push_back( make_pair( "lighting/lightWaterF.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) ); -	shaders.push_back( make_pair( "lighting/lightFullbrightWaterF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) ); -	shaders.push_back( make_pair( "lighting/lightShinyF.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) ); -	shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) ); -	shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) ); -	shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); +	S32 ch = gGLManager.mNumTextureImageUnits-1; + +	std::vector<S32> index_channels; +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl",		mVertexShaderLevel[SHADER_WINDLIGHT] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/gammaF.glsl",					mVertexShaderLevel[SHADER_WINDLIGHT]) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/atmosphericsF.glsl",			mVertexShaderLevel[SHADER_WINDLIGHT] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/transportF.glsl",				mVertexShaderLevel[SHADER_WINDLIGHT] ) );	 +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "environment/waterFogF.glsl",				mVertexShaderLevel[SHADER_WATER] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl",					mVertexShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightWaterNonIndexedF.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightWaterNonIndexedF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightShinyNonIndexedF.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightShinyNonIndexedF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightShinyWaterNonIndexedF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightF.glsl",					mVertexShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightWaterF.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightWaterF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightShinyF.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );  	for (U32 i = 0; i < shaders.size(); i++)  	{  		// Note usage of GL_FRAGMENT_SHADER_ARB -		if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB) == 0) +		if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, index_channels[i]) == 0)  		{  			return FALSE;  		} @@ -833,6 +879,9 @@ BOOL LLViewerShaderMgr::loadShadersEffects()  {  	BOOL success = TRUE; +	U32 samples = gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples")); +	bool multisample = samples > 1 && LLPipeline::sRenderDeferred && gGLManager.mHasTextureMultisample; +  	if (mVertexShaderLevel[SHADER_EFFECT] == 0)  	{  		gGlowProgram.unload(); @@ -858,10 +907,21 @@ BOOL LLViewerShaderMgr::loadShadersEffects()  	if (success)  	{ +		std::string fragment; + +		if (multisample) +		{ +			fragment = "effects/glowExtractMSF.glsl"; +		} +		else +		{ +			fragment = "effects/glowExtractF.glsl"; +		} +  		gGlowExtractProgram.mName = "Glow Extract Shader (Post)";  		gGlowExtractProgram.mShaderFiles.clear();  		gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB)); -		gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gGlowExtractProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gGlowExtractProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT];  		success = gGlowExtractProgram.createShader(NULL, &mGlowExtractUniforms);  		if (!success) @@ -925,6 +985,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	{  		gDeferredTreeProgram.unload();  		gDeferredDiffuseProgram.unload(); +		gDeferredNonIndexedDiffuseProgram.unload();  		gDeferredSkinnedDiffuseProgram.unload();  		gDeferredSkinnedBumpProgram.unload();  		gDeferredSkinnedAlphaProgram.unload(); @@ -945,6 +1006,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAvatarAlphaProgram.unload();  		gDeferredAlphaProgram.unload();  		gDeferredFullbrightProgram.unload(); +		gDeferredAvatarEyesProgram.unload();  		gDeferredPostGIProgram.unload();		  		gDeferredEdgeProgram.unload();		  		gDeferredPostProgram.unload();		 @@ -952,6 +1014,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredGIProgram.unload();  		gDeferredGIFinalProgram.unload();  		gDeferredWaterProgram.unload(); +		gDeferredWLSkyProgram.unload(); +		gDeferredWLCloudProgram.unload(); +		gDeferredStarProgram.unload();  		return TRUE;  	} @@ -959,18 +1024,33 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	BOOL success = TRUE; +	U32 samples = gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples")); +	bool multisample = samples > 1 && gGLManager.mHasTextureMultisample; +  	if (success)  	{  		gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader";  		gDeferredDiffuseProgram.mShaderFiles.clear();  		gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredDiffuseProgram.mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits;  		gDeferredDiffuseProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredDiffuseProgram.createShader(NULL, NULL);  	}  	if (success)  	{ +		gDeferredNonIndexedDiffuseProgram.mName = "Non Indexed Deferred Diffuse Shader"; +		gDeferredNonIndexedDiffuseProgram.mShaderFiles.clear(); +		gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredNonIndexedDiffuseProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		success = gDeferredNonIndexedDiffuseProgram.createShader(NULL, NULL); +	} +		 + +	if (success) +	{  		gDeferredSkinnedDiffuseProgram.mName = "Deferred Skinned Diffuse Shader";  		gDeferredSkinnedDiffuseProgram.mFeatures.hasObjectSkinning = true;  		gDeferredSkinnedDiffuseProgram.mShaderFiles.clear(); @@ -1000,9 +1080,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = true;  		gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true;  		gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = true; +		gDeferredSkinnedAlphaProgram.mFeatures.disableTextureIndex = true;  		gDeferredSkinnedAlphaProgram.mShaderFiles.clear();  		gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredSkinnedAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL);  	} @@ -1039,40 +1120,83 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ +		std::string fragment; + +		if (multisample) +		{ +			fragment = "deferred/pointLightMSF.glsl"; +		} +		else +		{ +			fragment = "deferred/pointLightF.glsl"; +		} +  		gDeferredLightProgram.mName = "Deferred Light Shader";  		gDeferredLightProgram.mShaderFiles.clear();  		gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredLightProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredLightProgram.createShader(NULL, NULL);  	}  	if (success)  	{ +		std::string fragment; +		if (multisample) +		{ +			fragment = "deferred/multiPointLightMSF.glsl"; +		} +		else +		{ +			fragment = "deferred/multiPointLightF.glsl"; +		} +  		gDeferredMultiLightProgram.mName = "Deferred MultiLight Shader";  		gDeferredMultiLightProgram.mShaderFiles.clear();  		gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredMultiLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredMultiLightProgram.createShader(NULL, NULL);  	}  	if (success)  	{ +		std::string fragment; + +		if (multisample) +		{ +			fragment = "deferred/spotLightMSF.glsl"; +		} +		else +		{ +			fragment = "deferred/multiSpotLightF.glsl"; +		} +  		gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader";  		gDeferredSpotLightProgram.mShaderFiles.clear();  		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredSpotLightProgram.createShader(NULL, NULL);  	}  	if (success)  	{ +		std::string fragment; + +		if (multisample) +		{ +			fragment = "deferred/multiSpotLightMSF.glsl"; +		} +		else +		{ +			fragment = "deferred/multiSpotLightF.glsl"; +		} +  		gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader";  		gDeferredMultiSpotLightProgram.mShaderFiles.clear();  		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredMultiSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL);  	} @@ -1083,11 +1207,25 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		if (gSavedSettings.getBOOL("RenderDeferredSSAO"))  		{ -			fragment = "deferred/sunLightSSAOF.glsl"; +			if (multisample) +			{ +				fragment = "deferred/sunlightSSAOMSF.glsl"; +			} +			else +			{ +				fragment = "deferred/sunLightSSAOF.glsl"; +			}  		}  		else  		{ -			fragment = "deferred/sunLightF.glsl"; +			if (multisample) +			{ +				fragment = "deferred/sunlightMSF.glsl"; +			} +			else +			{ +				fragment = "deferred/sunLightF.glsl"; +			}  		}  		gDeferredSunProgram.mName = "Deferred Sun Shader"; @@ -1100,10 +1238,21 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ +		std::string fragment; + +		if (multisample) +		{ +			fragment = "deferred/blurLightMSF.glsl"; +		} +		else +		{ +			fragment = "deferred/blurLightF.glsl"; +		} +  		gDeferredBlurLightProgram.mName = "Deferred Blur Light Shader";  		gDeferredBlurLightProgram.mShaderFiles.clear();  		gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredBlurLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredBlurLightProgram.createShader(NULL, NULL);  	} @@ -1116,6 +1265,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAlphaProgram.mFeatures.hasGamma = true;  		gDeferredAlphaProgram.mFeatures.hasAtmospherics = true;  		gDeferredAlphaProgram.mFeatures.hasLighting = true; +		gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels +		if (mVertexShaderLevel[SHADER_DEFERRED] < 1) +		{ +			gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits; +		} +		else +		{ //shave off some texture units for shadow maps +			gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits - 6; +		} +			  		gDeferredAlphaProgram.mShaderFiles.clear();  		gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1125,11 +1284,26 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ +		gDeferredAvatarEyesProgram.mName = "Deferred Avatar Eyes Shader"; +		gDeferredAvatarEyesProgram.mFeatures.calculatesAtmospherics = true; +		gDeferredAvatarEyesProgram.mFeatures.hasGamma = true; +		gDeferredAvatarEyesProgram.mFeatures.hasTransport = true; +		gDeferredAvatarEyesProgram.mFeatures.isFullbright = true; +		gDeferredAvatarEyesProgram.mFeatures.disableTextureIndex = true; +		gDeferredAvatarEyesProgram.mShaderFiles.clear(); +		gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredAvatarEyesProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		success = gDeferredAvatarEyesProgram.createShader(NULL, NULL); +	} + +	if (success) +	{  		gDeferredFullbrightProgram.mName = "Deferred Fullbright Shader";  		gDeferredFullbrightProgram.mFeatures.calculatesAtmospherics = true;  		gDeferredFullbrightProgram.mFeatures.hasGamma = true;  		gDeferredFullbrightProgram.mFeatures.hasTransport = true; -		gDeferredFullbrightProgram.mFeatures.isFullbright = true; +		gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits;  		gDeferredFullbrightProgram.mShaderFiles.clear();  		gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1153,10 +1327,21 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ +		std::string fragment; + +		if (multisample) +		{ +			fragment = "deferred/softenLightMSF.glsl"; +		} +		else +		{ +			fragment = "deferred/softenLightF.glsl"; +		} +  		gDeferredSoftenProgram.mName = "Deferred Soften Shader";  		gDeferredSoftenProgram.mShaderFiles.clear();  		gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredSoftenProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredSoftenProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; @@ -1230,41 +1415,106 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true;  		gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true;  		gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true; +		gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true;  		gDeferredAvatarAlphaProgram.mShaderFiles.clear();  		gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredAvatarAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredAvatarAlphaProgram.createShader(&mAvatarAttribs, &mAvatarUniforms);  	}  	if (success)  	{ +		std::string fragment; +		if (multisample) +		{ +			fragment = "deferred/postDeferredMSF.glsl"; +		} +		else +		{ +			fragment = "deferred/postDeferredF.glsl"; +		} +  		gDeferredPostProgram.mName = "Deferred Post Shader";  		gDeferredPostProgram.mShaderFiles.clear();  		gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredPostProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredPostProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredPostProgram.createShader(NULL, NULL);  	}  	if (success)  	{ +		std::string fragment; +		if (multisample) +		{ +			fragment = "deferred/postDeferredNoDoFMSF.glsl"; +		} +		else +		{ +			fragment = "deferred/postDeferredNoDoFF.glsl"; +		} +  		gDeferredPostNoDoFProgram.mName = "Deferred Post Shader";  		gDeferredPostNoDoFProgram.mShaderFiles.clear();  		gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredPostNoDoFProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredPostNoDoFProgram.createShader(NULL, NULL);  	} +	if (success) +	{ +		gDeferredWLSkyProgram.mName = "Deferred Windlight Sky Shader"; +		//gWLSkyProgram.mFeatures.hasGamma = true; +		gDeferredWLSkyProgram.mShaderFiles.clear(); +		gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredWLSkyProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY; +		success = gDeferredWLSkyProgram.createShader(NULL, &mWLUniforms); +	} + +	if (success) +	{ +		gDeferredWLCloudProgram.mName = "Deferred Windlight Cloud Program"; +		gDeferredWLCloudProgram.mShaderFiles.clear(); +		gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredWLCloudProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY; +		success = gDeferredWLCloudProgram.createShader(NULL, &mWLUniforms); +	} + +	if (success) +	{ +		gDeferredStarProgram.mName = "Deferred Star Program"; +		gDeferredStarProgram.mShaderFiles.clear(); +		gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredStarProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY; +		success = gDeferredStarProgram.createShader(NULL, &mWLUniforms); +	} +  	if (mVertexShaderLevel[SHADER_DEFERRED] > 1)  	{  		if (success)  		{ +			std::string fragment; +			if (multisample) +			{ +				fragment = "deferred/edgeMSF.glsl"; +			} +			else +			{ +				fragment = "deferred/edgeF.glsl"; +			} +  			gDeferredEdgeProgram.mName = "Deferred Edge Shader";  			gDeferredEdgeProgram.mShaderFiles.clear();  			gDeferredEdgeProgram.mShaderFiles.push_back(make_pair("deferred/edgeV.glsl", GL_VERTEX_SHADER_ARB)); -			gDeferredEdgeProgram.mShaderFiles.push_back(make_pair("deferred/edgeF.glsl", GL_FRAGMENT_SHADER_ARB)); +			gDeferredEdgeProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  			gDeferredEdgeProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  			success = gDeferredEdgeProgram.createShader(NULL, NULL);  		} @@ -1272,8 +1522,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (mVertexShaderLevel[SHADER_DEFERRED] > 2)  	{ -		 -  		if (success)  		{  			gDeferredPostGIProgram.mName = "Deferred Post GI Shader"; @@ -1321,7 +1569,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  BOOL LLViewerShaderMgr::loadShadersObject()  {  	BOOL success = TRUE; - +	  	if (mVertexShaderLevel[SHADER_OBJECT] == 0)  	{  		gObjectShinyProgram.unload(); @@ -1332,6 +1580,14 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleWaterProgram.unload();  		gObjectFullbrightProgram.unload();  		gObjectFullbrightWaterProgram.unload(); +		gObjectShinyNonIndexedProgram.unload(); +		gObjectFullbrightShinyNonIndexedProgram.unload(); +		gObjectFullbrightShinyNonIndexedWaterProgram.unload(); +		gObjectShinyNonIndexedWaterProgram.unload(); +		gObjectSimpleNonIndexedProgram.unload(); +		gObjectSimpleNonIndexedWaterProgram.unload(); +		gObjectFullbrightNonIndexedProgram.unload(); +		gObjectFullbrightNonIndexedWaterProgram.unload();  		gSkinnedObjectSimpleProgram.unload();  		gSkinnedObjectFullbrightProgram.unload();  		gSkinnedObjectFullbrightShinyProgram.unload(); @@ -1346,12 +1602,144 @@ BOOL LLViewerShaderMgr::loadShadersObject()  	if (success)  	{ +		gObjectSimpleNonIndexedProgram.mName = "Non indexed Shader"; +		gObjectSimpleNonIndexedProgram.mFeatures.calculatesLighting = true; +		gObjectSimpleNonIndexedProgram.mFeatures.calculatesAtmospherics = true; +		gObjectSimpleNonIndexedProgram.mFeatures.hasGamma = true; +		gObjectSimpleNonIndexedProgram.mFeatures.hasAtmospherics = true; +		gObjectSimpleNonIndexedProgram.mFeatures.hasLighting = true; +		gObjectSimpleNonIndexedProgram.mFeatures.disableTextureIndex = true; +		gObjectSimpleNonIndexedProgram.mShaderFiles.clear(); +		gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); +		gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gObjectSimpleNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		success = gObjectSimpleNonIndexedProgram.createShader(NULL, NULL); +	} +	 +	if (success) +	{ +		gObjectSimpleNonIndexedWaterProgram.mName = "Non indexed Water Shader"; +		gObjectSimpleNonIndexedWaterProgram.mFeatures.calculatesLighting = true; +		gObjectSimpleNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; +		gObjectSimpleNonIndexedWaterProgram.mFeatures.hasWaterFog = true; +		gObjectSimpleNonIndexedWaterProgram.mFeatures.hasAtmospherics = true; +		gObjectSimpleNonIndexedWaterProgram.mFeatures.hasLighting = true; +		gObjectSimpleNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; +		gObjectSimpleNonIndexedWaterProgram.mShaderFiles.clear(); +		gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); +		gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gObjectSimpleNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectSimpleNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; +		success = gObjectSimpleNonIndexedWaterProgram.createShader(NULL, NULL); +	} + +	if (success) +	{ +		gObjectFullbrightNonIndexedProgram.mName = "Non Indexed Fullbright Shader"; +		gObjectFullbrightNonIndexedProgram.mFeatures.calculatesAtmospherics = true; +		gObjectFullbrightNonIndexedProgram.mFeatures.hasGamma = true; +		gObjectFullbrightNonIndexedProgram.mFeatures.hasTransport = true; +		gObjectFullbrightNonIndexedProgram.mFeatures.isFullbright = true; +		gObjectFullbrightNonIndexedProgram.mFeatures.disableTextureIndex = true; +		gObjectFullbrightNonIndexedProgram.mShaderFiles.clear(); +		gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); +		gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gObjectFullbrightNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		success = gObjectFullbrightNonIndexedProgram.createShader(NULL, NULL); +	} + +	if (success) +	{ +		gObjectFullbrightNonIndexedWaterProgram.mName = "Non Indexed Fullbright Water Shader"; +		gObjectFullbrightNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; +		gObjectFullbrightNonIndexedWaterProgram.mFeatures.isFullbright = true; +		gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasWaterFog = true;		 +		gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasTransport = true; +		gObjectFullbrightNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; +		gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.clear(); +		gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); +		gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gObjectFullbrightNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectFullbrightNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; +		success = gObjectFullbrightNonIndexedWaterProgram.createShader(NULL, NULL); +	} + +	if (success) +	{ +		gObjectShinyNonIndexedProgram.mName = "Non Indexed Shiny Shader"; +		gObjectShinyNonIndexedProgram.mFeatures.calculatesAtmospherics = true; +		gObjectShinyNonIndexedProgram.mFeatures.calculatesLighting = true; +		gObjectShinyNonIndexedProgram.mFeatures.hasGamma = true; +		gObjectShinyNonIndexedProgram.mFeatures.hasAtmospherics = true; +		gObjectShinyNonIndexedProgram.mFeatures.isShiny = true; +		gObjectShinyNonIndexedProgram.mFeatures.disableTextureIndex = true; +		gObjectShinyNonIndexedProgram.mShaderFiles.clear(); +		gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); +		gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));		 +		gObjectShinyNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		success = gObjectShinyNonIndexedProgram.createShader(NULL, &mShinyUniforms); +	} + +	if (success) +	{ +		gObjectShinyNonIndexedWaterProgram.mName = "Non Indexed Shiny Water Shader"; +		gObjectShinyNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; +		gObjectShinyNonIndexedWaterProgram.mFeatures.calculatesLighting = true; +		gObjectShinyNonIndexedWaterProgram.mFeatures.isShiny = true; +		gObjectShinyNonIndexedWaterProgram.mFeatures.hasWaterFog = true; +		gObjectShinyNonIndexedWaterProgram.mFeatures.hasAtmospherics = true; +		gObjectShinyNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; +		gObjectShinyNonIndexedWaterProgram.mShaderFiles.clear(); +		gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); +		gObjectShinyNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; +		success = gObjectShinyNonIndexedWaterProgram.createShader(NULL, &mShinyUniforms); +	} +	 +	if (success) +	{ +		gObjectFullbrightShinyNonIndexedProgram.mName = "Non Indexed Fullbright Shiny Shader"; +		gObjectFullbrightShinyNonIndexedProgram.mFeatures.calculatesAtmospherics = true; +		gObjectFullbrightShinyNonIndexedProgram.mFeatures.isFullbright = true; +		gObjectFullbrightShinyNonIndexedProgram.mFeatures.isShiny = true; +		gObjectFullbrightShinyNonIndexedProgram.mFeatures.hasGamma = true; +		gObjectFullbrightShinyNonIndexedProgram.mFeatures.hasTransport = true; +		gObjectFullbrightShinyNonIndexedProgram.mFeatures.disableTextureIndex = true; +		gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.clear(); +		gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); +		gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gObjectFullbrightShinyNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		success = gObjectFullbrightShinyNonIndexedProgram.createShader(NULL, &mShinyUniforms); +	} + +	if (success) +	{ +		gObjectFullbrightShinyNonIndexedWaterProgram.mName = "Non Indexed Fullbright Shiny Water Shader"; +		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; +		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.isFullbright = true; +		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.isShiny = true; +		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasGamma = true; +		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasTransport = true; +		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasWaterFog = true; +		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; +		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.clear(); +		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); +		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; +		success = gObjectFullbrightShinyNonIndexedWaterProgram.createShader(NULL, &mShinyUniforms); +	} + +	if (success) +	{  		gObjectSimpleProgram.mName = "Simple Shader";  		gObjectSimpleProgram.mFeatures.calculatesLighting = true;  		gObjectSimpleProgram.mFeatures.calculatesAtmospherics = true;  		gObjectSimpleProgram.mFeatures.hasGamma = true;  		gObjectSimpleProgram.mFeatures.hasAtmospherics = true;  		gObjectSimpleProgram.mFeatures.hasLighting = true; +		gObjectSimpleProgram.mFeatures.mIndexedTextureChannels = 0;  		gObjectSimpleProgram.mShaderFiles.clear();  		gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1367,6 +1755,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleWaterProgram.mFeatures.hasWaterFog = true;  		gObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true;  		gObjectSimpleWaterProgram.mFeatures.hasLighting = true; +		gObjectSimpleWaterProgram.mFeatures.mIndexedTextureChannels = 0;  		gObjectSimpleWaterProgram.mShaderFiles.clear();  		gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1382,6 +1771,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightProgram.mFeatures.hasGamma = true;  		gObjectFullbrightProgram.mFeatures.hasTransport = true;  		gObjectFullbrightProgram.mFeatures.isFullbright = true; +		gObjectFullbrightProgram.mFeatures.mIndexedTextureChannels = 0;  		gObjectFullbrightProgram.mShaderFiles.clear();  		gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1396,6 +1786,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightWaterProgram.mFeatures.isFullbright = true;  		gObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true;		  		gObjectFullbrightWaterProgram.mFeatures.hasTransport = true; +		gObjectFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = 0;  		gObjectFullbrightWaterProgram.mShaderFiles.clear();  		gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1412,6 +1803,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectShinyProgram.mFeatures.hasGamma = true;  		gObjectShinyProgram.mFeatures.hasAtmospherics = true;  		gObjectShinyProgram.mFeatures.isShiny = true; +		gObjectShinyProgram.mFeatures.mIndexedTextureChannels = 0;  		gObjectShinyProgram.mShaderFiles.clear();  		gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));		 @@ -1427,6 +1819,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectShinyWaterProgram.mFeatures.isShiny = true;  		gObjectShinyWaterProgram.mFeatures.hasWaterFog = true;  		gObjectShinyWaterProgram.mFeatures.hasAtmospherics = true; +		gObjectShinyWaterProgram.mFeatures.mIndexedTextureChannels = 0;  		gObjectShinyWaterProgram.mShaderFiles.clear();  		gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1443,6 +1836,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightShinyProgram.mFeatures.isShiny = true;  		gObjectFullbrightShinyProgram.mFeatures.hasGamma = true;  		gObjectFullbrightShinyProgram.mFeatures.hasTransport = true; +		gObjectFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = 0;  		gObjectFullbrightShinyProgram.mShaderFiles.clear();  		gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1459,6 +1853,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightShinyWaterProgram.mFeatures.hasGamma = true;  		gObjectFullbrightShinyWaterProgram.mFeatures.hasTransport = true;  		gObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true; +		gObjectFullbrightShinyWaterProgram.mFeatures.mIndexedTextureChannels = 0;  		gObjectFullbrightShinyWaterProgram.mShaderFiles.clear();  		gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1478,6 +1873,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectSimpleProgram.mFeatures.hasAtmospherics = true;  			gSkinnedObjectSimpleProgram.mFeatures.hasLighting = true;  			gSkinnedObjectSimpleProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectSimpleProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectSimpleProgram.mShaderFiles.clear();  			gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1493,6 +1889,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightProgram.mFeatures.hasTransport = true;  			gSkinnedObjectFullbrightProgram.mFeatures.isFullbright = true;  			gSkinnedObjectFullbrightProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectFullbrightProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectFullbrightProgram.mShaderFiles.clear();  			gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1509,6 +1906,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightShinyProgram.mFeatures.isShiny = true;  			gSkinnedObjectFullbrightShinyProgram.mFeatures.isFullbright = true;  			gSkinnedObjectFullbrightShinyProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectFullbrightShinyProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.clear();  			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1525,6 +1923,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectShinySimpleProgram.mFeatures.hasAtmospherics = true;  			gSkinnedObjectShinySimpleProgram.mFeatures.hasObjectSkinning = true;  			gSkinnedObjectShinySimpleProgram.mFeatures.isShiny = true; +			gSkinnedObjectShinySimpleProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectShinySimpleProgram.mShaderFiles.clear();  			gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1540,9 +1939,11 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectSimpleWaterProgram.mFeatures.hasGamma = true;  			gSkinnedObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true;  			gSkinnedObjectSimpleWaterProgram.mFeatures.hasLighting = true; +			gSkinnedObjectSimpleWaterProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectSimpleWaterProgram.mFeatures.hasWaterFog = true;  			gSkinnedObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  			gSkinnedObjectSimpleWaterProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectSimpleWaterProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectSimpleWaterProgram.mShaderFiles.clear();  			gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1559,6 +1960,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightWaterProgram.mFeatures.isFullbright = true;  			gSkinnedObjectFullbrightWaterProgram.mFeatures.hasObjectSkinning = true;  			gSkinnedObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true; +			gSkinnedObjectFullbrightWaterProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  			gSkinnedObjectFullbrightWaterProgram.mShaderFiles.clear();  			gSkinnedObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1577,6 +1979,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true;  			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasObjectSkinning = true;  			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true; +			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  			gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.clear();  			gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1595,6 +1998,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasObjectSkinning = true;  			gSkinnedObjectShinySimpleWaterProgram.mFeatures.isShiny = true;  			gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasWaterFog = true; +			gSkinnedObjectShinySimpleWaterProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectShinySimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  			gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.clear();  			gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1635,6 +2039,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()  		gAvatarProgram.mFeatures.hasGamma = true;  		gAvatarProgram.mFeatures.hasAtmospherics = true;  		gAvatarProgram.mFeatures.hasLighting = true; +		gAvatarProgram.mFeatures.disableTextureIndex = true;  		gAvatarProgram.mShaderFiles.clear();  		gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));  		gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1650,6 +2055,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()  			gAvatarWaterProgram.mFeatures.hasWaterFog = true;  			gAvatarWaterProgram.mFeatures.hasAtmospherics = true;  			gAvatarWaterProgram.mFeatures.hasLighting = true; +			gAvatarWaterProgram.mFeatures.disableTextureIndex = true;  			gAvatarWaterProgram.mShaderFiles.clear();  			gAvatarWaterProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));  			gAvatarWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1670,6 +2076,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()  	{  		gAvatarPickProgram.mName = "Avatar Pick Shader";  		gAvatarPickProgram.mFeatures.hasSkinning = true; +		gAvatarPickProgram.mFeatures.disableTextureIndex = true;  		gAvatarPickProgram.mShaderFiles.clear();  		gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER_ARB));  		gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1686,6 +2093,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()  		gAvatarEyeballProgram.mFeatures.hasGamma = true;  		gAvatarEyeballProgram.mFeatures.hasAtmospherics = true;  		gAvatarEyeballProgram.mFeatures.hasLighting = true; +		gAvatarEyeballProgram.mFeatures.disableTextureIndex = true;  		gAvatarEyeballProgram.mShaderFiles.clear();  		gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER_ARB));  		gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER_ARB)); diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 72ac5e02ee..6ecba65470 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -298,16 +298,25 @@ extern LLVector4			gShinyOrigin;  //object shaders  extern LLGLSLShader			gObjectSimpleProgram;  extern LLGLSLShader			gObjectSimpleWaterProgram; +extern LLGLSLShader			gObjectSimpleNonIndexedProgram; +extern LLGLSLShader			gObjectSimpleNonIndexedWaterProgram;  extern LLGLSLShader			gObjectFullbrightProgram;  extern LLGLSLShader			gObjectFullbrightWaterProgram; +extern LLGLSLShader			gObjectFullbrightNonIndexedProgram; +extern LLGLSLShader			gObjectFullbrightNonIndexedWaterProgram;  extern LLGLSLShader			gObjectSimpleLODProgram;  extern LLGLSLShader			gObjectFullbrightLODProgram;  extern LLGLSLShader			gObjectFullbrightShinyProgram;  extern LLGLSLShader			gObjectFullbrightShinyWaterProgram; +extern LLGLSLShader			gObjectFullbrightShinyNonIndexedProgram; +extern LLGLSLShader			gObjectFullbrightShinyNonIndexedWaterProgram; +  extern LLGLSLShader			gObjectShinyProgram;  extern LLGLSLShader			gObjectShinyWaterProgram; +extern LLGLSLShader			gObjectShinyNonIndexedProgram; +extern LLGLSLShader			gObjectShinyNonIndexedWaterProgram;  extern LLGLSLShader			gSkinnedObjectSimpleProgram;  extern LLGLSLShader			gSkinnedObjectFullbrightProgram; @@ -349,6 +358,7 @@ extern LLGLSLShader			gDeferredImpostorProgram;  extern LLGLSLShader			gDeferredEdgeProgram;  extern LLGLSLShader			gDeferredWaterProgram;  extern LLGLSLShader			gDeferredDiffuseProgram; +extern LLGLSLShader			gDeferredNonIndexedDiffuseProgram;  extern LLGLSLShader			gDeferredSkinnedDiffuseProgram;  extern LLGLSLShader			gDeferredSkinnedBumpProgram;  extern LLGLSLShader			gDeferredSkinnedAlphaProgram; @@ -373,8 +383,11 @@ extern LLGLSLShader			gDeferredAvatarShadowProgram;  extern LLGLSLShader			gDeferredAttachmentShadowProgram;  extern LLGLSLShader			gDeferredAlphaProgram;  extern LLGLSLShader			gDeferredFullbrightProgram; +extern LLGLSLShader			gDeferredAvatarEyesProgram;  extern LLGLSLShader			gDeferredAvatarAlphaProgram; - +extern LLGLSLShader			gDeferredWLSkyProgram; +extern LLGLSLShader			gDeferredWLCloudProgram; +extern LLGLSLShader			gDeferredStarProgram;  extern LLGLSLShader			gLuminanceGatherProgram;  //current avatar shader parameter pointer diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index af06421bf9..4da0f80a00 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1168,6 +1168,7 @@ void LLViewerFetchedTexture::init(bool firstinit)  	mSavedRawDiscardLevel = -1 ;  	mDesiredSavedRawDiscardLevel = -1 ;  	mLastReferencedSavedRawImageTime = 0.0f ; +	mKeptSavedRawImageTime = 0.f ;  	mLastCallBackActiveTime = 0.f;  } @@ -2696,8 +2697,16 @@ void LLViewerFetchedTexture::saveRawImage()  	mLastReferencedSavedRawImageTime = sCurrentTime ;  } -void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard)  +void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard, F32 kept_time)   {  +	mKeptSavedRawImageTime = kept_time ; +	mLastReferencedSavedRawImageTime = sCurrentTime ; + +	if(mSavedRawDiscardLevel > -1 && mSavedRawDiscardLevel <= desired_discard) +	{ +		return ; //raw imge is ready. +	} +  	if(!mForceToSaveRawImage || mDesiredSavedRawDiscardLevel < 0 || mDesiredSavedRawDiscardLevel > desired_discard)  	{  		mForceToSaveRawImage = TRUE ; @@ -2713,11 +2722,16 @@ void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard)  			mRawImage = NULL ;  			mRawDiscardLevel = INVALID_DISCARD_LEVEL ; -		} +		}		  	}  }  void LLViewerFetchedTexture::destroySavedRawImage()  { +	if(mLastReferencedSavedRawImageTime < mKeptSavedRawImageTime) +	{ +		return ; //keep the saved raw image. +	} +  	mForceToSaveRawImage  = FALSE ;  	mSaveRawImage = FALSE ; @@ -2729,6 +2743,7 @@ void LLViewerFetchedTexture::destroySavedRawImage()  	mSavedRawDiscardLevel = -1 ;  	mDesiredSavedRawDiscardLevel = -1 ;  	mLastReferencedSavedRawImageTime = 0.0f ; +	mKeptSavedRawImageTime = 0.f ;  }  LLImageRaw* LLViewerFetchedTexture::getSavedRawImage()  diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index d512f8ec3a..c5b8c8923a 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -465,7 +465,7 @@ public:  	S32         getCachedRawImageLevel() const {return mCachedRawDiscardLevel;}  	BOOL        isCachedRawImageReady() const {return mCachedRawImageReady ;}  	BOOL        isRawImageValid()const { return mIsRawImageValid ; }	 -	void        forceToSaveRawImage(S32 desired_discard = 0) ; +	void        forceToSaveRawImage(S32 desired_discard = 0, F32 kept_time = 0.f) ;  	/*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ;  	void        destroySavedRawImage() ;  	LLImageRaw* getSavedRawImage() ; @@ -550,6 +550,7 @@ protected:  	S32 mSavedRawDiscardLevel;  	S32 mDesiredSavedRawDiscardLevel;  	F32 mLastReferencedSavedRawImageTime ; +	F32 mKeptSavedRawImageTime ;  	//a small version of the copy of the raw image (<= 64 * 64)  	LLPointer<LLImageRaw> mCachedRawImage; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 34d15a597e..b1441cc281 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -601,7 +601,7 @@ public:  			ypos += y_inc; -			if (gSavedSettings.getBOOL("MeshEnabled")) +			if (gMeshRepo.meshRezEnabled())  			{  				addText(xpos, ypos, llformat("%.3f MB Mesh Data Received", LLMeshRepository::sBytesReceived/(1024.f*1024.f))); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index ec2b5a4c98..1b53348b43 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -56,6 +56,7 @@  #include "lleditingmotion.h"  #include "llemote.h"  //#include "llfirstuse.h" +#include "llfloatertools.h"  #include "llheadrotmotion.h"  #include "llhudeffecttrail.h"  #include "llhudmanager.h" @@ -1541,7 +1542,35 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  				return TRUE;  			}  		} + +		if (isSelf()) +		{ +			for (attachment_map_t::iterator iter = mAttachmentPoints.begin();  +			 iter != mAttachmentPoints.end(); +			 ++iter) +			{ +				LLViewerJointAttachment* attachment = iter->second; + +				for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +					 attachment_iter != attachment->mAttachedObjects.end(); +					 ++attachment_iter) +				{ +					LLViewerObject* attached_object = (*attachment_iter); +					 +					if (attached_object && !attached_object->isDead() && attachment->getValid()) +					{ +						LLDrawable* drawable = attached_object->mDrawable; +						if (drawable->isState(LLDrawable::RIGGED)) +						{ //regenerate octree for rigged attachment +							gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED, TRUE); +						} +					} +				} +			} +		}  	} + +	  	LLVector3 position;  	if (mNameText.notNull() && mNameText->lineSegmentIntersect(start, end, position)) @@ -1557,6 +1586,56 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  	return FALSE;  } +LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end, +									  S32 face, +									  BOOL pick_transparent, +									  S32* face_hit, +									  LLVector3* intersection, +									  LLVector2* tex_coord, +									  LLVector3* normal, +									  LLVector3* bi_normal) +{ +	if (isSelf() && !gAgent.needsRenderAvatar()) +	{ +		return NULL; +	} + +	LLViewerObject* hit = NULL; + +	if (lineSegmentBoundingBox(start, end)) +	{ +		LLVector3 local_end = end; +		LLVector3 local_intersection; + +		for (attachment_map_t::iterator iter = mAttachmentPoints.begin();  +			iter != mAttachmentPoints.end(); +			++iter) +		{ +			LLViewerJointAttachment* attachment = iter->second; + +			for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +					attachment_iter != attachment->mAttachedObjects.end(); +					++attachment_iter) +			{ +				LLViewerObject* attached_object = (*attachment_iter); +					 +				if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, bi_normal)) +				{ +					local_end = local_intersection; +					if (intersection) +					{ +						*intersection = local_intersection; +					} +					 +					hit = attached_object; +				} +			} +		} +	} +		 +	return hit; +} +  //-----------------------------------------------------------------------------  // parseSkeletonFile()  //----------------------------------------------------------------------------- @@ -4968,19 +5047,6 @@ void LLVOAvatar::resetSpecificJointPosition( const std::string& name )  //-----------------------------------------------------------------------------  void LLVOAvatar::resetJointPositionsToDefault( void )  { -	const LLVector3& avPos = getCharacterPosition(); -	 -	//Reposition the pelvis -	LLJoint* pPelvis = mRoot.findJoint("mPelvis"); -	if ( pPelvis ) -	{ -		pPelvis->setPosition( avPos + pPelvis->getPosition() ); -	} -	else  -	{ -		llwarns<<"Can't get pelvis joint."<<llendl;	 -		return; -	}  	//Subsequent joints are relative to pelvis  	for( S32 i = 0; i < (S32)mNumJoints; ++i ) @@ -4991,7 +5057,7 @@ void LLVOAvatar::resetJointPositionsToDefault( void )  			pJoint->setId( LLUUID::null );  			//restore joints to default positions, however skip over the pelvis -			if ( pJoint && pPelvis != pJoint ) +			if ( pJoint )  			{  				pJoint->restoreOldXform();  			} @@ -6017,7 +6083,7 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )  		LLVOVolume* pVObj = pVO->mDrawable->getVOVolume();  		if ( pVObj )  		{ -			const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID() ); +			const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID(), pVObj );  			if ( pSkinData )  			{  				const int jointCnt = pSkinData->mJointNames.size(); @@ -6028,6 +6094,14 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )  					if ( bindCnt > 0 )  					{  						LLVOAvatar::resetJointPositionsToDefault(); +						//Need to handle the repositioning of the cam, updating rig data etc during outfit editing  +						//This handles the case where we detach a replacement rig. +						if ( gAgentCamera.cameraCustomizeAvatar() ) +						{ +							gAgent.unpauseAnimation(); +							//Still want to refocus on head bone +							gAgentCamera.changeCameraToCustomizeAvatar(); +						}  					}  				}  			}				 diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 295799fd24..03c0498a2a 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -145,6 +145,14 @@ public:  												 LLVector2* tex_coord = NULL,      // return the texture coordinates of the intersection point  												 LLVector3* normal = NULL,         // return the surface normal at the intersection point  												 LLVector3* bi_normal = NULL);     // return the surface bi-normal at the intersection point +	LLViewerObject*	lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end, +												 S32 face = -1,                    // which face to check, -1 = ALL_SIDES +												 BOOL pick_transparent = FALSE, +												 S32* face_hit = NULL,             // which face was hit +												 LLVector3* intersection = NULL,   // return the intersection point +												 LLVector2* tex_coord = NULL,      // return the texture coordinates of the intersection point +												 LLVector3* normal = NULL,         // return the surface normal at the intersection point +												 LLVector3* bi_normal = NULL);     // return the surface bi-normal at the intersection point  	//--------------------------------------------------------------------  	// LLCharacter interface and related diff --git a/indra/newview/llvoclouds.cpp b/indra/newview/llvoclouds.cpp index 78aa6e6ab8..478708cd78 100644 --- a/indra/newview/llvoclouds.cpp +++ b/indra/newview/llvoclouds.cpp @@ -244,9 +244,13 @@ void LLVOClouds::getGeometry(S32 te,  	vtx[2] = puff_pos_agent + right + up;  	vtx[3] = puff_pos_agent + right - up; +	verticesp->mV[3] = 0.f;  	*verticesp++  = vtx[0]; +	verticesp->mV[3] = 0.f;  	*verticesp++  = vtx[1]; +	verticesp->mV[3] = 0.f;  	*verticesp++  = vtx[2]; +	verticesp->mV[3] = 0.f;  	*verticesp++  = vtx[3];  	*texcoordsp++ = uvs[0]; diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 6f354b78b1..a4b0910c92 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -324,10 +324,18 @@ void LLVOPartGroup::getGeometry(S32 idx,  	LLVector3 normal = -LLViewerCamera::getInstance()->getXAxis(); -		 + +	//HACK -- the verticesp->mV[3] = 0.f here are to set the texture index to 0 (particles don't use texture batching, maybe they should) +	// this works because there is actually a 4th float stored after the vertex position which is used as a texture index +	// also, somebody please VECTORIZE THIS + +	verticesp->mV[3] = 0.f;  	*verticesp++ = part_pos_agent + up - right; +	verticesp->mV[3] = 0.f;  	*verticesp++ = part_pos_agent - up - right; +	verticesp->mV[3] = 0.f;  	*verticesp++ = part_pos_agent + up + right; +	verticesp->mV[3] = 0.f;  	*verticesp++ = part_pos_agent - up + right;  	*colorsp++ = part.mColor; @@ -360,7 +368,7 @@ U32 LLVOPartGroup::getPartitionType() const  }  LLParticlePartition::LLParticlePartition() -: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK, TRUE, GL_STREAM_DRAW_ARB) +: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB)  {  	mRenderPass = LLRenderPass::PASS_ALPHA;  	mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES; @@ -418,6 +426,7 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co  			mFaceList.push_back(facep);  			vertex_count += facep->getGeomCount();  			index_count += facep->getIndicesCount(); +			llassert(facep->getIndicesCount() < 65536);  		}  		obj->mDepth /= count; diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 6396bc042d..800af26b69 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -1483,6 +1483,8 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons  		facep->setVertexBuffer(buff);  	} +	llassert(facep->getVertexBuffer()->getNumIndices() == 6); +  	index_offset = facep->getGeometry(verticesp,normalsp,texCoordsp, indicesp);  	if (-1 == index_offset) diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index dbcd4f50ca..510525259f 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -375,6 +375,8 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep,  	S32 num_vertices, num_indices;  	U32 index; +	llassert(mLastStride > 0); +  	render_stride = mLastStride;  	patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();  	S32 vert_size = patch_size / render_stride; diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 8946d4e0b6..3c7fe708e6 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -980,11 +980,6 @@ void LLVOTree::appendMesh(LLStrider<LLVector3>& vertices,  	for (S32 i = 0; i < index_count; i++)  	{  		U16 index = index_offset + i; -		if (idx[index] >= vert_start + vert_count || -			idx[index] < vert_start) -		{ -			llerrs << "WTF?" << llendl; -		}  		*indices++ = idx[index]-vert_start+cur_idx;  	} diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index e9a8c9b80a..c5e2c56e4b 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -73,6 +73,7 @@  #include "llagent.h"  #include "llviewermediafocus.h"  #include "lldatapacker.h" +#include "llviewershadermgr.h"  #include "llvoavatar.h"  #include "llvocache.h" @@ -1095,8 +1096,6 @@ void LLVOVolume::updateSculptTexture()  } - -  void LLVOVolume::notifyMeshLoaded()  {   	mSculptChanged = TRUE; @@ -1222,7 +1221,7 @@ BOOL LLVOVolume::calcLOD()  	}  	//hold onto unmodified distance for debugging -	F32 debug_distance = distance; +	//F32 debug_distance = distance;  	distance *= sDistanceFactor; @@ -1245,7 +1244,9 @@ BOOL LLVOVolume::calcLOD()  	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO))  	{ -		setDebugText(llformat("%.2f:%.2f, %d", debug_distance, radius, cur_detail)); +		//setDebugText(llformat("%.2f:%.2f, %d", debug_distance, radius, cur_detail)); + +		setDebugText(llformat("%d", mDrawable->getFace(0)->getTextureIndex()));  	}  	if (cur_detail != mLOD) @@ -1274,6 +1275,15 @@ BOOL LLVOVolume::updateLOD()  		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE);  		mLODChanged = TRUE;  	} +	else +	{ +		F32 new_radius = getBinRadius(); +		F32 old_radius = mDrawable->getBinRadius(); +		if (new_radius < old_radius * 0.9f || new_radius > old_radius*1.1f) +		{ +			gPipeline.markPartitionMove(mDrawable); +		} +	}  	lod_changed = lod_changed || LLViewerObject::updateLOD(); @@ -3086,16 +3096,28 @@ U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const  F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes)  { +	F32 radius = getScale().length(); +  	if (isMesh())  	{	  		LLSD& header = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID()); -		F32 radius = getScale().length(); -		  		return LLMeshRepository::getStreamingCost(header, radius, bytes, visible_bytes, mLOD);  	} -		 -	return 0.f; +	else +	{ +		LLVolume* volume = getVolume(); +		S32 counts[4]; +		LLVolume::getLoDTriangleCounts(volume->getParams(), counts); + +		LLSD header; +		header["lowest_lod"]["size"] = counts[0] * 10; +		header["low_lod"]["size"] = counts[1] * 10; +		header["medium_lod"]["size"] = counts[2] * 10; +		header["high_lod"]["size"] = counts[3] * 10; + +		return LLMeshRepository::getStreamingCost(header, radius); +	}	  }  U32 LLVOVolume::getTriangleCount() @@ -3187,6 +3209,10 @@ F32 LLVOVolume::getBinRadius()  	F32 scale = 1.f; +	S32 size_factor = llmax(gSavedSettings.getS32("OctreeStaticObjectSizeFactor"), 1); +	S32 attachment_size_factor = llmax(gSavedSettings.getS32("OctreeAttachmentSizeFactor"), 1); +	LLVector3 distance_factor = gSavedSettings.getVector3("OctreeDistanceFactor"); +	LLVector3 alpha_distance_factor = gSavedSettings.getVector3("OctreeAlphaDistanceFactor");  	const LLVector4a* ext = mDrawable->getSpatialExtents();  	BOOL shrink_wrap = mDrawable->isAnimating(); @@ -3216,6 +3242,8 @@ F32 LLVOVolume::getBinRadius()  		radius = llmin(bounds.mV[1], bounds.mV[2]);  		radius = llmin(radius, bounds.mV[0]);  		radius *= 0.5f; +		radius *= 1.f+mDrawable->mDistanceWRTCamera*alpha_distance_factor[1]; +		radius += mDrawable->mDistanceWRTCamera*alpha_distance_factor[0];  	}  	else if (shrink_wrap)  	{ @@ -3226,24 +3254,19 @@ F32 LLVOVolume::getBinRadius()  	}  	else if (mDrawable->isStatic())  	{ -		/*if (mDrawable->getRadius() < 2.0f) -		{ -			radius = 16.f; -		} -		else -		{ -			radius = llmax(mDrawable->getRadius(), 32.f); -		}*/ - -		radius = (((S32) mDrawable->getRadius())/2+1)*8; +		radius = llmax((S32) mDrawable->getRadius(), 1)*size_factor; +		radius *= 1.f + mDrawable->mDistanceWRTCamera * distance_factor[1]; +		radius += mDrawable->mDistanceWRTCamera * distance_factor[0];  	}  	else if (mDrawable->getVObj()->isAttachment())  	{ -		radius = (((S32) (mDrawable->getRadius()*4)+1))*2; +		radius = llmax((S32) mDrawable->getRadius(),1)*attachment_size_factor;  	}  	else  	{ -		radius = 8.f; +		radius = mDrawable->getRadius(); +		radius *= 1.f + mDrawable->mDistanceWRTCamera * distance_factor[1]; +		radius += mDrawable->mDistanceWRTCamera * distance_factor[0];  	}  	return llclamp(radius*scale, 0.5f, 256.f); @@ -3342,7 +3365,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  	{  		if (LLFloater::isVisible(gFloaterTools) && getAvatar()->isSelf())  		{ -			gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED, TRUE); +			updateRiggedVolume(); +			genBBoxes(FALSE);  			volume = mRiggedVolume;  			transform = false;  		} @@ -3521,7 +3545,7 @@ void LLVOVolume::updateRiggedVolume()  	LLVolume* volume = getVolume(); -	const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(volume->getParams().getSculptID()); +	const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(volume->getParams().getSculptID(), this);  	if (!skin)  	{ @@ -3712,6 +3736,21 @@ LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep)  	mSlopRatio = 0.25f;  } +bool can_batch_texture(LLFace* facep) +{ +	if (facep->getTextureEntry()->getBumpmap()) +	{ //bump maps aren't worked into texture batching yet +		return false; +	} + +	if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE) +	{ //texture animation breaks batches +		return false; +	} +	 +	return true; +} +  void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type)  {  	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -3762,12 +3801,36 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  	LLViewerTexture* tex = facep->getTexture(); +	U8 index = facep->getTextureIndex(); + +	bool batchable = false; + +	if (index < 255 && idx >= 0) +	{ +		if (index < draw_vec[idx]->mTextureList.size()) +		{ +			if (draw_vec[idx]->mTextureList[index].isNull()) +			{ +				batchable = true; +				draw_vec[idx]->mTextureList[index] = tex; +			} +			else if (draw_vec[idx]->mTextureList[index] == tex) +			{ //this face's texture index can be used with this batch +				batchable = true; +			} +		} +		else +		{ //texture list can be expanded to fit this texture index +			batchable = true; +		} +	} +	  	U8 glow = (U8) (facep->getTextureEntry()->getGlow() * 255);  	if (idx >= 0 &&   		draw_vec[idx]->mVertexBuffer == facep->getVertexBuffer() &&  		draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && -		(LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex) && +		(LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex || batchable) &&  #if LL_DARWIN  		draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange &&  		draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && @@ -3781,6 +3844,12 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		draw_vec[idx]->mCount += facep->getIndicesCount();  		draw_vec[idx]->mEnd += facep->getGeomCount();  		draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize()); + +		if (index >= draw_vec[idx]->mTextureList.size()) +		{ +			draw_vec[idx]->mTextureList.resize(index+1); +			draw_vec[idx]->mTextureList[index] = tex; +		}  		draw_vec[idx]->validate();  		update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]);  		update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[1]); @@ -3811,6 +3880,11 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  			draw_info->mDrawMode = LLRender::TRIANGLE_STRIP;  		} +		if (index < 255) +		{ //initialize texture list for texture batching +			draw_info->mTextureList.resize(index+1); +			draw_info->mTextureList[index] = tex; +		}  		draw_info->validate();  	}  } @@ -3910,7 +3984,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  		LLVOVolume* vobj = drawablep->getVOVolume(); -		if (vobj->getVolume() && vobj->getVolume()->isTetrahedron()) +		if (vobj->getVolume() && vobj->getVolume()->isTetrahedron() || (vobj->isMesh() && !gMeshRepo.meshRezEnabled()))  		{  			continue;  		} @@ -3923,7 +3997,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  		bool rigged = vobj->isAttachment() &&   					vobj->isMesh() &&  -					gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID()); +					gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj);  		bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); @@ -3965,7 +4039,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  				if ( pAvatarVO )  				{  					LLUUID currentId = vobj->getVolume()->getParams().getSculptID(); -					const LLMeshSkinInfo*  pSkinData = gMeshRepo.getSkinInfo( currentId ); +					const LLMeshSkinInfo*  pSkinData = gMeshRepo.getSkinInfo( currentId, vobj );  					if ( pSkinData )  					{ @@ -4233,15 +4307,24 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	U32 bump_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;  	U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; -	if (LLPipeline::sRenderDeferred) +	bool batch_textures = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1; + +	if (batch_textures)  	{  		bump_mask |= LLVertexBuffer::MAP_BINORMAL; +		genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, FALSE, TRUE); +		genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, FALSE, TRUE); +		genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, FALSE, TRUE); +		genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, TRUE, TRUE); +	} +	else +	{ +		genDrawInfo(group, simple_mask, simple_faces); +		genDrawInfo(group, fullbright_mask, fullbright_faces); +		genDrawInfo(group, bump_mask, bump_faces, FALSE, TRUE); +		genDrawInfo(group, alpha_mask, alpha_faces, TRUE);  	} -	genDrawInfo(group, simple_mask, simple_faces); -	genDrawInfo(group, bump_mask, bump_faces); -	genDrawInfo(group, fullbright_mask, fullbright_faces); -	genDrawInfo(group, alpha_mask, alpha_faces, TRUE);  	if (!LLPipeline::sDelayVBUpdate)  	{ @@ -4297,11 +4380,6 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  						face->getGeometryVolume(*volume, face->getTEOffset(),   							vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex());  					} - -					if (!face) -					{ -						llerrs << "WTF?" << llendl; -					}  				}  				drawablep->clearState(LLDrawable::REBUILD_ALL); @@ -4356,13 +4434,37 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  		group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);  	} -	if (group && group->isState(LLSpatialGroup::NEW_DRAWINFO)) +	llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO)); +} + +struct CompareBatchBreakerModified +{ +	bool operator()(const LLFace* const& lhs, const LLFace* const& rhs)  	{ -		llerrs << "WTF?" << llendl; +		const LLTextureEntry* lte = lhs->getTextureEntry(); +		const LLTextureEntry* rte = rhs->getTextureEntry(); + +		if (lte->getBumpmap() != rte->getBumpmap()) +		{ +			return lte->getBumpmap() < rte->getBumpmap(); +		} +		else if (lte->getFullbright() != rte->getFullbright()) +		{ +			return lte->getFullbright() < rte->getFullbright(); +		} +		else  if (lte->getGlow() != rte->getGlow()) +		{ +			return lte->getGlow() < rte->getGlow(); +		} +		else +		{ +			return lhs->getTexture() < rhs->getTexture(); +		} +		  	} -} +}; -void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort) +void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures)  {  	//calculate maximum number of vertices to store in a single buffer  	U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); @@ -4371,7 +4473,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  	if (!distance_sort)  	{  		//sort faces by things that break batches -		std::sort(faces.begin(), faces.end(), LLFace::CompareBatchBreaker()); +		std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified());  	}  	else  	{ @@ -4391,6 +4493,16 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  		buffer_index = -1;  	} +	S32 texture_index_channels = gGLManager.mNumTextureImageUnits-1; //always reserve one for shiny for now just for simplicity +	 +	if (LLPipeline::sRenderDeferred && distance_sort) +	{ +		texture_index_channels = gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels; +	} + +	texture_index_channels = llmin(texture_index_channels, (S32) gSavedSettings.getU32("RenderMaxTextureIndex")); +	 +  	while (face_iter != faces.end())  	{  		//pull off next face @@ -4421,24 +4533,101 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  		std::vector<LLFace*>::iterator i = face_iter;  		++i; -		while (i != faces.end() &&  -			(LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) +		std::vector<LLViewerTexture*> texture_list; + +		if (batch_textures)  		{ -			facep = *i; -			 -			if (geom_count + facep->getGeomCount() > max_vertices) -			{ //cut batches on geom count too big -				break; +			U8 cur_tex = 0; +			facep->setTextureIndex(cur_tex); +			texture_list.push_back(tex); + +			//if (can_batch_texture(facep)) +			{ +				while (i != faces.end()) +				{ +					facep = *i; +					if (facep->getTexture() != tex) +					{ +						if (distance_sort) +						{ //textures might be out of order, see if texture exists in current batch +							bool found = false; +							for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx) +							{ +								if (facep->getTexture() == texture_list[tex_idx]) +								{ +									cur_tex = tex_idx; +									found = true; +									break; +								} +							} + +							if (!found) +							{ +								cur_tex = texture_list.size(); +							} +						} +						else +						{ +							cur_tex++; +						} + +						if (!can_batch_texture(facep)) +						{ //face is bump mapped or has an animated texture matrix -- can't  +							//batch more than 1 texture at a time +							break; +						} + +						if (cur_tex >= texture_index_channels) +						{ //cut batches when index channels are depleted +							break; +						} + +						tex = facep->getTexture(); + +						texture_list.push_back(tex); +					} + +					if (geom_count + facep->getGeomCount() > max_vertices) +					{ //cut batches on geom count too big +						break; +					} + +					++i; +					index_count += facep->getIndicesCount(); +					geom_count += facep->getGeomCount(); + +					facep->setTextureIndex(cur_tex); +				}  			} -			++i; -			index_count += facep->getIndicesCount(); -			geom_count += facep->getGeomCount(); +			tex = texture_list[0]; +		} +		else +		{ +			while (i != faces.end() &&  +				(LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) +			{ +				facep = *i; +			 + +				//face has no texture index +				facep->mDrawInfo = NULL; +				facep->setTextureIndex(255); + +				if (geom_count + facep->getGeomCount() > max_vertices) +				{ //cut batches on geom count too big +					break; +				} + +				++i; +				index_count += facep->getIndicesCount(); +				geom_count += facep->getGeomCount(); +			}  		}  		//create/delete/resize vertex buffer if needed  		LLVertexBuffer* buffer = NULL; -		LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(tex); +		LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(*face_iter);  		if (found_iter != group->mBufferMap[mask].end())  		{ @@ -4469,7 +4658,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  			}  		} -		buffer_map[mask][tex].push_back(buffer); +		buffer_map[mask][*face_iter].push_back(buffer);  		//add face geometry @@ -4483,6 +4672,11 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  			facep->setGeomIndex(index_offset);  			facep->setVertexBuffer(buffer);	 +			if (batch_textures && facep->getTextureIndex() == 255) +			{ +				llerrs << "Invalid texture index." << llendl; +			} +			  			{  				//for debugging, set last time face was updated vs moved  				facep->updateRebuildFlags(); @@ -4495,12 +4689,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  					U32 te_idx = facep->getTEOffset(); -					if (facep->getGeometryVolume(*volume, te_idx,  -						vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset)) -					{ -						buffer->markDirty(facep->getGeomIndex(), facep->getGeomCount(),  -							facep->getIndicesStart(), facep->getIndicesCount()); -					} +					facep->getGeometryVolume(*volume, te_idx,  +						vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset);  				}  			} @@ -4681,7 +4871,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun  			{  				vertex_count += facep->getGeomCount();  				index_count += facep->getIndicesCount(); - +				llassert(facep->getIndicesCount() < 65536);  				//remember face (for sorting)  				mFaceList.push_back(facep);  			} diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 845a87b8cf..e74bf2a620 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -392,6 +392,7 @@ void LLPipeline::init()  {  	LLMemType mt(LLMemType::MTYPE_PIPELINE_INIT); +	gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity");  	sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");  	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");  	sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); @@ -580,11 +581,6 @@ void LLPipeline::allocatePhysicsBuffer()  	if (mPhysicsDisplay.getWidth() != resX || mPhysicsDisplay.getHeight() != resY)  	{  		mPhysicsDisplay.allocate(resX, resY, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); -		if (mSampleBuffer.getWidth() == mPhysicsDisplay.getWidth() &&  -			mSampleBuffer.getHeight() == mPhysicsDisplay.getHeight()) -		{ -			mPhysicsDisplay.setSampleBuffer(&mSampleBuffer); -		}  	}  } @@ -594,8 +590,9 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  	mScreenWidth = resX;  	mScreenHeight = resY; -	//never use more than 4 samples for render targets -	U32 samples = llmin(gSavedSettings.getU32("RenderFSAASamples"), (U32) 4); +	//cap samples at 4 for render targets to avoid out of memory errors +	U32 samples = gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples")); +  	if (gGLManager.mIsATI)  	{ //disable multisampling of render targets where ATI is involved  		samples = 0; @@ -621,11 +618,11 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		bool gi = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED);  		//allocate deferred rendering color buffers -		mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); -		mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); +		mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples); +		mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples);  		addDeferredAttachments(mDeferredScreen); -		mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); +		mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples);		  #if LL_DARWIN  		// As of OS X 10.6.7, Apple doesn't support multiple color formats in a single FBO @@ -636,7 +633,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		if (shadow_detail > 0 || ssao)  		{ //only need mDeferredLight[0] for shadows OR ssao -			mDeferredLight[0].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +			mDeferredLight[0].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);  		}  		else  		{ @@ -645,7 +642,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		if (ssao)  		{ //only need mDeferredLight[1] for ssao -			mDeferredLight[1].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +			mDeferredLight[1].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, false);  		}  		else  		{ @@ -654,7 +651,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		if (gi)  		{ //only need mDeferredLight[2] and mGIMapPost for gi -			mDeferredLight[2].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +			mDeferredLight[2].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, false);  			for (U32 i = 0; i < 2; i++)  			{  #if LL_DARWIN @@ -744,35 +741,9 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE);		  	} -	if (LLRenderTarget::sUseFBO && samples > 1) -	{  -		mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples); -		if (LLPipeline::sRenderDeferred) -		{ -			addDeferredAttachments(mSampleBuffer); -			mDeferredScreen.setSampleBuffer(&mSampleBuffer); -			mEdgeMap.setSampleBuffer(&mSampleBuffer); -		} - -		mScreen.setSampleBuffer(&mSampleBuffer); - -		stop_glerror(); -	} -	else -	{ -		mSampleBuffer.release(); -	} -	  	if (LLPipeline::sRenderDeferred)  	{ //share depth buffer between deferred targets  		mDeferredScreen.shareDepthBuffer(mScreen); -		for (U32 i = 0; i < 3; i++) -		{ //share stencil buffer with screen space lightmap to stencil out sky -			if (mDeferredLight[i].getTexture(0)) -			{ -				mDeferredScreen.shareDepthBuffer(mDeferredLight[i]); -			} -		}  	}  	gGL.getTexUnit(0)->disable(); @@ -802,16 +773,7 @@ void LLPipeline::updateRenderDeferred()  //static  void LLPipeline::refreshRenderDeferred()  { -	if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) -	{ -		//turn the deferred rendering and glow off when draw physics shapes. -		sRenderDeferred = FALSE ; -		sRenderGlow = FALSE ; -	} -	else -	{ -		updateRenderDeferred() ; -	} +	updateRenderDeferred();  }  void LLPipeline::releaseGLBuffers() @@ -841,7 +803,6 @@ void LLPipeline::releaseGLBuffers()  	mScreen.release();  	mPhysicsDisplay.release();  	mUIScreen.release(); -	mSampleBuffer.release();  	mDeferredScreen.release();  	mDeferredDepth.release();  	for (U32 i = 0; i < 3; i++) @@ -2550,6 +2511,32 @@ void LLPipeline::markGLRebuild(LLGLUpdate* glu)  	}  } +void LLPipeline::markPartitionMove(LLDrawable* drawable) +{ +	if (!drawable->isState(LLDrawable::PARTITION_MOVE) &&  +		!drawable->getPositionGroup().equals3(LLVector4a::getZero())) +	{ +		drawable->setState(LLDrawable::PARTITION_MOVE); +		mPartitionQ.push_back(drawable); +	} +} + +void LLPipeline::processPartitionQ() +{ +	for (LLDrawable::drawable_list_t::iterator iter = mPartitionQ.begin(); iter != mPartitionQ.end(); ++iter) +	{ +		LLDrawable* drawable = *iter; +		if (!drawable->isDead()) +		{ +			drawable->updateBinRadius(); +			drawable->movePartition(); +		} +		drawable->clearState(LLDrawable::PARTITION_MOVE); +	} + +	mPartitionQ.clear(); +} +  void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority)  {  	LLMemType mt(LLMemType::MTYPE_PIPELINE); @@ -3610,7 +3597,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)  					if (gDebugGL)  					{  						check_stack_depth(stack_depth); -						std::string msg = llformat("%s pass %d", gPoolNames[cur_type].c_str(), i); +						std::string msg = llformat("pass %d", i);  						LLGLState::checkStates(msg);  						LLGLState::checkTextureChannels(msg);  						LLGLState::checkClientArrays(msg); @@ -4085,6 +4072,37 @@ void LLPipeline::renderDebug()  	bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD); +	if (!hud_only && !mDebugBlips.empty()) +	{ //render debug blips +		glPointSize(8.f); +		LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); + +		gGL.begin(LLRender::POINTS); +		for (std::list<DebugBlip>::iterator iter = mDebugBlips.begin(); iter != mDebugBlips.end(); ) +		{ +			DebugBlip& blip = *iter; + +			blip.mAge += gFrameIntervalSeconds; +			if (blip.mAge > 2.f) +			{ +				mDebugBlips.erase(iter++); +			} +			else +			{ +				iter++; +			} + +			blip.mPosition.mV[2] += gFrameIntervalSeconds*2.f; + +			gGL.color4fv(blip.mColor.mV); +			gGL.vertex3fv(blip.mPosition.mV); +		} +		gGL.end(); +		gGL.flush(); +		glPointSize(1.f); +	} + +  	// Debug stuff.  	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();   			iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -5919,7 +5937,6 @@ LLSpatialPartition* LLPipeline::getSpatialPartition(LLViewerObject* vobj)  	return NULL;  } -  void LLPipeline::resetVertexBuffers(LLDrawable* drawable)  {  	if (!drawable || drawable->isDead()) @@ -6065,7 +6082,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  {  	LLMemType mt_ru(LLMemType::MTYPE_PIPELINE_RENDER_BLOOM);  	if (!(gPipeline.canUseVertexShaders() && -		sRenderGlow)) +		sRenderGlow) || +		(!sRenderDeferred && hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)))  	{  		return;  	} @@ -6111,67 +6129,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  	gGL.setColorMask(true, true);  	glClearColor(0,0,0,0); - -	/*if (for_snapshot) -	{ -		gGL.getTexUnit(0)->bind(&mGlow[1]); -		{ -			//LLGLEnable stencil(GL_STENCIL_TEST); -			//glStencilFunc(GL_NOTEQUAL, 255, 0xFFFFFFFF); -			//glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); -			//LLGLDisable blend(GL_BLEND); - -			// If the snapshot is constructed from tiles, calculate which -			// tile we're in. - -			//from LLViewerCamera::setPerpsective -			if (zoom_factor > 1.f) -			{ -				int pos_y = subfield / llceil(zoom_factor); -				int pos_x = subfield - (pos_y*llceil(zoom_factor)); -				F32 size = 1.f/zoom_factor; - -				tc1.set(pos_x*size, pos_y*size); -				tc2 = tc1 + LLVector2(size,size); -			} -			else -			{ -				tc2.set(1,1); -			} -			 -			LLGLEnable blend(GL_BLEND); -			gGL.setSceneBlendType(LLRender::BT_ADD); -			 -				 -			gGL.begin(LLRender::TRIANGLE_STRIP); -			gGL.color4f(1,1,1,1); -			gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); -			gGL.vertex2f(-1,-1); -			 -			gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); -			gGL.vertex2f(-1,1); -			 -			gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); -			gGL.vertex2f(1,-1); -			 -			gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); -			gGL.vertex2f(1,1); - -			gGL.end(); - -			gGL.flush(); -			gGL.setSceneBlendType(LLRender::BT_ALPHA); -		} - -		gGL.flush(); -		glMatrixMode(GL_PROJECTION); -		glPopMatrix(); -		glMatrixMode(GL_MODELVIEW); -		glPopMatrix(); - -		return; -	}*/ -	 +		  	{  		{  			LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); @@ -6195,11 +6153,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);  		gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); -		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);		 -		gGL.getTexUnit(0)->disable(); -		gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE); -		gGL.getTexUnit(0)->bind(&mScreen); - +		mScreen.bindTexture(0, 0); +		  		gGL.color4f(1,1,1,1);  		gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));  		gGL.begin(LLRender::TRIANGLE_STRIP); @@ -6214,7 +6169,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  		gGL.end(); -		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); +		gGL.getTexUnit(0)->unbind(mScreen.getUsage());  		mGlow[2].flush();  	} @@ -6242,7 +6197,6 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  	for (S32 i = 0; i < kernel; i++)  	{ -		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  		{  			LLFastTimer ftm(FTM_RENDER_BLOOM_FBO);  			mGlow[i%2].bindTarget(); @@ -6303,9 +6257,9 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  	LLVertexBuffer::unbind(); -	if (LLPipeline::sRenderDeferred && !LLViewerCamera::getInstance()->cameraUnderWater()) +	if (LLPipeline::sRenderDeferred)  	{ -		bool dof_enabled = true; +		bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater();  		LLGLSLShader* shader = &gDeferredPostProgram;  		if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) @@ -6313,7 +6267,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  			shader = &gDeferredGIFinalProgram;  			dof_enabled = false;  		} -		else if (LLToolMgr::getInstance()->inBuildMode() || !gSavedSettings.getBOOL("RenderDepthOfField")) +		else if (!dof_enabled || LLToolMgr::getInstance()->inBuildMode() || !gSavedSettings.getBOOL("RenderDepthOfField"))  		{ //squish focal length when in build mode (or if DoF is disabled) so DoF doesn't make editing objects difficult  			shader = &gDeferredPostNoDoFProgram;  			dof_enabled = false; @@ -6435,11 +6389,10 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  			shader->uniform1f("magnification", magnification);  		} -		S32 channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); +		S32 channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());  		if (channel > -1)  		{  			mScreen.bindTexture(0, channel); -			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);  		}  		//channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE);  		//if (channel > -1) @@ -6532,6 +6485,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  	if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))  	{ +		gGL.setColorMask(true, false); +  		LLVector2 tc1(0,0);  		LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw()*2,  				  (F32) gViewerWindow->getWorldViewHeightRaw()*2); @@ -6578,25 +6533,23 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen  		noise_map = mNoiseMap;  	} -	LLGLState::checkTextureChannels(); -  	shader.bind();  	S32 channel = 0; -	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); +	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage());  	if (channel > -1)  	{  		mDeferredScreen.bindTexture(0,channel);  		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);  	} -	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); +	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage());  	if (channel > -1)  	{  		mDeferredScreen.bindTexture(1, channel);  		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);  	} -	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); +	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage());  	if (channel > -1)  	{  		mDeferredScreen.bindTexture(2, channel); @@ -6719,22 +6672,16 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen  			shader.uniformMatrix4fv("gi_norm_mat", 1, FALSE, mGINormalMatrix.m);  		}  	} -	 -	/*channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); -	if (channel > -1) -	{ -		mDeferredScreen.bindTexture(3, channel); -	}*/ +	stop_glerror(); -	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); +	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, mDeferredDepth.getUsage());  	if (channel > -1)  	{  		gGL.getTexUnit(channel)->bind(&mDeferredDepth, TRUE); -		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);  		stop_glerror(); -		glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);		 -		glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA);		 +		//glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);		 +		//glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA);		  		stop_glerror(); @@ -6763,7 +6710,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen  	stop_glerror(); -	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE); +	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, mDeferredLight[light_index].getUsage());  	if (channel > -1)  	{  		mDeferredLight[light_index].bindTexture(0, channel); @@ -6983,9 +6930,9 @@ void LLPipeline::renderDeferredLighting()  		}  		//ati doesn't seem to love actually using the stencil buffer on FBO's -		LLGLEnable stencil(GL_STENCIL_TEST); -		glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); -		glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); +		LLGLDisable stencil(GL_STENCIL_TEST); +		//glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); +		//glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);  		gGL.setColorMask(true, true); @@ -7787,33 +7734,41 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)  	LLViewerTexture* img = volume->getLightTexture(); +	if (img == NULL) +	{ +		img = LLViewerFetchedTexture::sWhiteImagep; +	} +  	S32 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); -	if (channel > -1 && img) +	if (channel > -1)  	{ -		gGL.getTexUnit(channel)->bind(img); +		if (img) +		{ +			gGL.getTexUnit(channel)->bind(img); -		F32 lod_range = logf(img->getWidth())/logf(2.f); +			F32 lod_range = logf(img->getWidth())/logf(2.f); -		shader.uniform1f("proj_focus", focus); -		shader.uniform1f("proj_lod", lod_range); -		shader.uniform1f("proj_ambient_lod", llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f)); +			shader.uniform1f("proj_focus", focus); +			shader.uniform1f("proj_lod", lod_range); +			shader.uniform1f("proj_ambient_lod", llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f)); +		}  	} +		  }  void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)  {  	stop_glerror(); -	shader.disableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); -	shader.disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); -	shader.disableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); -	shader.disableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); -	shader.disableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); -	shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE); +	shader.disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage()); +	shader.disableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage()); +	shader.disableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage()); +	shader.disableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, mDeferredScreen.getUsage()); +	shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, mDeferredLight[0].getUsage());  	shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE); -	shader.disableTexture(LLViewerShaderMgr::DEFERRED_EDGE, LLTexUnit::TT_RECT_TEXTURE); -	shader.disableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, LLTexUnit::TT_RECT_TEXTURE); -	shader.disableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, LLTexUnit::TT_RECT_TEXTURE); +	shader.disableTexture(LLViewerShaderMgr::DEFERRED_EDGE, mEdgeMap.getUsage()); +	shader.disableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, mDeferredLight[1].getUsage()); +	shader.disableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, mDeferredLight[2].getUsage());  	shader.disableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE);  	shader.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);  	shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MIP); @@ -7860,8 +7815,6 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)  	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  	gGL.getTexUnit(0)->activate();  	shader.unbind(); - -	LLGLState::checkTextureChannels();  }  inline float sgn(float a) @@ -9409,6 +9362,11 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  			mShadow[i+4].flush();   		}  	} +	else +	{ //no spotlight shadows +		mShadowSpotLight[0] = mShadowSpotLight[1] = NULL; +	} +  	if (!gSavedSettings.getBOOL("CameraOffset"))  	{ @@ -9831,4 +9789,9 @@ void LLPipeline::clearRenderTypeMask(U32 type, ...)  	}  } +void LLPipeline::addDebugBlip(const LLVector3& position, const LLColor4& color) +{ +	DebugBlip blip(position, color); +	mDebugBlips.push_back(blip); +} diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index e9a250cd6d..e9da25e544 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -157,7 +157,8 @@ public:  	void		markGLRebuild(LLGLUpdate* glu);  	void		markRebuild(LLSpatialGroup* group, BOOL priority = FALSE);  	void        markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, BOOL priority = FALSE); -		 +	void		markPartitionMove(LLDrawable* drawablep); +  	//get the object between start and end that's closest to start.  	LLViewerObject* lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end,  												BOOL pick_transparent, @@ -211,6 +212,7 @@ public:  	void updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip = 0, LLPlane* plane = NULL);  //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane  	void createObjects(F32 max_dtime);  	void createObject(LLViewerObject* vobj); +	void processPartitionQ();  	void updateGeom(F32 max_dtime);  	void updateGL();  	void rebuildPriorityGroups(); @@ -358,6 +360,8 @@ public:  	static void updateRenderDeferred();  	static void refreshRenderDeferred(); +	void addDebugBlip(const LLVector3& position, const LLColor4& color); +  private:  	void unloadShaders();  	void addToQuickLookup( LLDrawPool* new_poolp ); @@ -524,7 +528,6 @@ public:  	LLRenderTarget			mEdgeMap;  	LLRenderTarget			mDeferredDepth;  	LLRenderTarget			mDeferredLight[3]; -	LLMultisampleBuffer		mSampleBuffer;  	LLRenderTarget			mGIMap;  	LLRenderTarget			mGIMapPost[2];  	LLRenderTarget			mLuminanceMap; @@ -637,6 +640,9 @@ protected:  	LLDrawable::drawable_list_t 	mBuildQ2; // non-priority  	LLSpatialGroup::sg_vector_t		mGroupQ1; //priority  	LLSpatialGroup::sg_vector_t		mGroupQ2; // non-priority + +	LLDrawable::drawable_list_t		mPartitionQ; //drawables that need to update their spatial partition radius  +  	bool mGroupQ2Locked;  	bool mGroupQ1Locked; @@ -726,6 +732,20 @@ public:  protected:  	std::vector<LLFace*>		mSelectedFaces; +	class DebugBlip +	{ +	public: +		LLColor4 mColor; +		LLVector3 mPosition; +		F32 mAge; + +		DebugBlip(const LLVector3& position, const LLColor4& color) +			: mColor(color), mPosition(position), mAge(0.f) +		{ } +	}; + +	std::list<DebugBlip> mDebugBlips; +  	LLPointer<LLViewerFetchedTexture>	mFaceSelectImagep;  	U32						mLightMask; diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index dce55dae12..f58595b3c5 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -4,9 +4,11 @@       name="Model Preview" title="Upload Model" width="620">    <string name="status_idle">Idle</string> +  <string name="status_parse_error">Dae parsing issue - see log for details.</string>    <string name="status_reading_file">Loading...</string>    <string name="status_generating_meshes">Generating Meshes...</string>    <string name="status_vertex_number_overflow">Error: Vertex number is more than 65534, aborted!</string> +  <string name="bad_element">Error: element is invalid</string>    <string name="high">High</string>    <string name="medium">Medium</string>    <string name="low">Low</string> @@ -83,6 +85,20 @@      </text>    </panel> +  <check_box +	height="16" +	left_delta="0" +	name="confirm_checkbox" +	top_pad="15" +	follows="bottom|left" +	width="16" /> + +  <text +	height="30" +	width="570" +	word_wrap="true"  +	left_delta="25" +	top_delta="0">I confirm that I have the appropriate rights to the material contained in this model. [secondlife:///app/floater/learn_more Learn more]</text>    <text left="10" bottom="540" width="290" height="15" follows="bottom|left|right" name="status">[STATUS]</text> diff --git a/indra/newview/skins/default/xui/en/floater_model_wizard.xml b/indra/newview/skins/default/xui/en/floater_model_wizard.xml index 47b2e5fd79..8603682e3a 100644 --- a/indra/newview/skins/default/xui/en/floater_model_wizard.xml +++ b/indra/newview/skins/default/xui/en/floater_model_wizard.xml @@ -1019,9 +1019,11 @@ Advanced users familiar with 3d content creation tools may prefer to use the [se  	<spinner visible="false" left="10" height="20" follows="top|left" width="80" top_pad="-50" value="1.0" min_val="0.01" max_val="64.0" name="import_scale"/>  	<string name="status_idle">Idle</string> +  <string name="status_parse_error">Dae parsing issue - see log for details.</string>  	<string name="status_reading_file">Loading...</string>  	<string name="status_generating_meshes">Generating Meshes...</string> -  <string name="status_vertex_number_overflow">Error: Vertex number is more than 65534, aborted!</string> +	<string name="status_vertex_number_overflow">Error: Vertex number is more than 65534, aborted!</string> +	<string name="bad_element">Error: element is invalid</string>  	<string name="high">High</string>  	<string name="medium">Medium</string>  	<string name="low">Low</string> diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 40bf7bfed7..7441b2cd9c 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -2098,11 +2098,7 @@ even though the user gets a free copy.                   label="Cylinder"                   name="Cylinder"                   value="Cylinder" /> -              <combo_box.item -                 label="Mesh" -                 name="Mesh" -                 value="Mesh" /> -            </combo_box> +              </combo_box>          </panel>          <panel           border="false" @@ -2461,8 +2457,9 @@ even though the user gets a free copy.               height="19"               increment="0.1"               initial_value="0" -             label="Density" +             label="Density in 100 kg/m^3"               label_width="70" +             label_wrap="true"               layout="topleft"               left_delta="0"               max_val="22587" @@ -2483,7 +2480,7 @@ even though the user gets a free copy.               max_val="1"               min_val="0"               name="Physics Restitution" -             top_pad="4" +             top_pad="8"               width="132" />          </panel>           <panel diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index ce96c488b4..09105c1d28 100644..100755 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6823,7 +6823,9 @@ Select residents to share with.      name="MeshUploadError"      icon="alert.tga"      type="alert"> -    [LABEL] failed to upload: [MESSAGE] [IDENTIFIER] [INVALIDITY_IDENTIFIER] +    [LABEL] failed to upload: [MESSAGE] [IDENTIFIER]  + +See the log file for details.    </notification>    <notification  | 
