From 9a832999d9567da7e39eb37b04557bbd3ec0c098 Mon Sep 17 00:00:00 2001
From: "Karl Stiefvater (qarl)" <qarl@lindenlab.com>
Date: Fri, 28 May 2010 14:33:29 -0500
Subject: fix unloaded no-particle avatar sphere to be fullbright, no black
 flicker.  reviewed by Nyx.

---
 indra/llrender/llrendersphere.cpp | 86 +++++++++++++++++++++------------------
 indra/llrender/llrendersphere.h   |  4 ++
 2 files changed, 51 insertions(+), 39 deletions(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llrendersphere.cpp b/indra/llrender/llrendersphere.cpp
index e22b753923..212963f270 100644
--- a/indra/llrender/llrendersphere.cpp
+++ b/indra/llrender/llrendersphere.cpp
@@ -68,45 +68,6 @@ void drawSolidSphere(GLdouble radius, GLint slices, GLint stacks)
 }
 
 
-// lat = 0 is Z-axis
-// lon = 0, lat = 90 at X-axis
-void lat2xyz(LLVector3 * result, F32 lat, F32 lon)
-{
-	// Convert a latitude and longitude to x,y,z on a normal sphere and return it in result
-	F32 r;
-	result->mV[VX] = (F32) (cos(lon * DEG_TO_RAD) * sin(lat * DEG_TO_RAD));
-	result->mV[VY] = (F32) (sin(lon * DEG_TO_RAD) * sin(lat * DEG_TO_RAD));
-	r = (F32) pow(result->mV[VX] * result->mV[VX] + result->mV[VY] * result->mV[VY], 0.5f);
-	if (r == 1.0f) 
-	{
-		result->mV[VZ] = 0.0f;
-	}
-	else
-	{
-		result->mV[VZ] = (F32) pow(1 - r*r, 0.5f);
-		if (lat > 90.01)
-		{
-			result->mV[VZ] *= -1.0;
-		}
-	}
-}
-
-void lat2xyz_rad(LLVector3 * result, F32 lat, F32 lon)
-{
-	// Convert a latitude and longitude to x,y,z on a normal sphere and return it in result
-	F32 r;
-	result->mV[VX] = (F32) (cos(lon) * sin(lat));
-	result->mV[VY] = (F32) (sin(lon) * sin(lat));
-	r = (F32) pow(result->mV[VX] * result->mV[VX] + result->mV[VY] * result->mV[VY], 0.5f);
-	if (r == 1.0f) 
-		result->mV[VZ] = 0.0f;
-	else
-	{
-		result->mV[VZ] = (F32) pow(1 - r*r, 0.5f);
-		if (lat > F_PI_BY_TWO) result->mV[VZ] *= -1.0;
-	}
-}
-
 // A couple thoughts on sphere drawing:
 // 1) You need more slices than stacks, but little less than 2:1
 // 2) At low LOD, setting stacks to an odd number avoids a "band" around the equator, making things look smoother
@@ -181,3 +142,50 @@ void LLRenderSphere::render()
 {
 	glCallList(mDList[0]);
 }
+
+inline LLVector3 polar_to_cart(F32 latitude, F32 longitude)
+{
+	return LLVector3(sin(F_TWO_PI * latitude) * cos(F_TWO_PI * longitude),
+					 sin(F_TWO_PI * latitude) * sin(F_TWO_PI * longitude),
+					 cos(F_TWO_PI * latitude));
+}
+
+
+void LLRenderSphere::renderGGL()
+{
+	S32 const LATITUDE_SLICES = 20;
+	S32 const LONGITUDE_SLICES = 30;
+
+	if (mSpherePoints.empty())
+	{
+		mSpherePoints.resize(LATITUDE_SLICES + 1);
+		for (S32 lat_i = 0; lat_i < LATITUDE_SLICES + 1; lat_i++)
+		{
+			mSpherePoints[lat_i].resize(LONGITUDE_SLICES + 1);
+			for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES + 1; lon_i++)
+			{
+				F32 lat = (F32)lat_i / LATITUDE_SLICES;
+				F32 lon = (F32)lon_i / LONGITUDE_SLICES;
+
+				mSpherePoints[lat_i][lon_i] = polar_to_cart(lat, lon);
+			}
+		}
+	}
+	
+	gGL.begin(LLRender::TRIANGLES);
+
+	for (S32 lat_i = 0; lat_i < LATITUDE_SLICES; lat_i++)
+	{
+		for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES; lon_i++)
+		{
+			gGL.vertex3fv(mSpherePoints[lat_i][lon_i].mV);
+			gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV);
+			gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV);
+
+			gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV);
+			gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV);
+			gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i+1].mV);
+		}
+	}
+	gGL.end();
+}
diff --git a/indra/llrender/llrendersphere.h b/indra/llrender/llrendersphere.h
index 617ee3e12e..ebc71b6146 100644
--- a/indra/llrender/llrendersphere.h
+++ b/indra/llrender/llrendersphere.h
@@ -52,6 +52,10 @@ public:
 	void cleanupGL();
 	void render(F32 pixel_area);		// of a box of size 1.0 at that position
 	void render();						// render at highest LOD
+	void renderGGL();                   // render using LLRender
+
+private:
+	std::vector< std::vector<LLVector3> > mSpherePoints;
 };
 
 extern LLRenderSphere gSphere;
-- 
cgit v1.2.3