Commits

Jason McKesson committed 21f6aff

Tut12: All objects now properly positions. They have individual materials.

  • Participants
  • Parent commits 2bfc6e4

Comments (0)

Files changed (19)

File Tut 12 Dynamic Range/Lights.cpp

 	m_lightTimers.push_back(Framework::Timer(Framework::Timer::TT_LOOP, 15.0f));
 }
 
+struct UpdateTimer
+{
+	void operator()(Framework::Timer &timer) {timer.Update();}
+	void operator()(std::pair<const std::string, Framework::Timer> &timeData)
+	{timeData.second.Update();}
+};
+
+struct PauseTimer
+{
+	void operator()(Framework::Timer &timer) {timer.TogglePause();}
+	void operator()(std::pair<const std::string, Framework::Timer> &timeData)
+	{timeData.second.TogglePause();}
+};
+
 void LightManager::UpdateTime()
 {
 	m_keyLightTimer.Update();
-	for(size_t loop = 0; loop < m_lightTimers.size(); loop++)
-	{
-		m_lightTimers[loop].Update();
-	}
+	std::for_each(m_lightTimers.begin(), m_lightTimers.end(), UpdateTimer());
+	std::for_each(m_extraTimers.begin(), m_extraTimers.end(), UpdateTimer());
 }
 
 bool LightManager::TogglePause()
 {
-	for(size_t loop = 0; loop < m_lightTimers.size(); loop++)
-	{
-		m_lightTimers[loop].TogglePause();
-	}
+	std::for_each(m_lightTimers.begin(), m_lightTimers.end(), PauseTimer());
+	std::for_each(m_extraTimers.begin(), m_extraTimers.end(), PauseTimer());
 
 	return m_keyLightTimer.TogglePause();
 }
 	lightData.lightAttenuation = g_fLightAttenuation;
 
 	lightData.lights[0].cameraSpaceLightPos =
-		worldToCameraMat * glm::vec4(0.0f, 1.0f, 0.0f, 0.0f);
+		worldToCameraMat * glm::vec4(0.0f, 0.981f, 0.196f, 0.0f);
 
 	lightData.lights[0].lightIntensity = glm::vec4(0.1f, 0.1f, 0.1f, 1.0f);
 
 		glm::vec4 lightPosCameraSpace = worldToCameraMat * worldLightPos;
 
 		lightData.lights[light].cameraSpaceLightPos = lightPosCameraSpace;
-		lightData.lights[light].lightIntensity = glm::vec4(0.3f, 0.3f, 0.3f, 1.0f);
+		lightData.lights[light].lightIntensity = glm::vec4(0.2f, 0.2f, 0.2f, 1.0f);
 	}
 
 	return lightData;
 {
 	return m_lightPos[lightIx].Interpolate(m_lightTimers[lightIx].GetAlpha());
 }
+
+void LightManager::CreateTimer( const std::string &timerName,
+							   Framework::Timer::Type eType, float fDuration )
+{
+	m_extraTimers[timerName] = Framework::Timer(eType, fDuration);
+}
+
+float LightManager::GetTimerValue( const std::string &timerName ) const
+{
+	ExtraTimerMap::const_iterator loc = m_extraTimers.find(timerName);
+
+	if(loc == m_extraTimers.end())
+		return -1.0f;
+
+	return loc->second.GetAlpha();
+}
+

File Tut 12 Dynamic Range/Lights.h

 #ifndef LIGHTS_H
 #define LIGHTS_H
 
+#include <map>
 #include "../framework/Timer.h"
 #include <glm/glm.hpp>
 #include "../framework/Interpolators.h"
 	int GetNumberOfPointLights() const;
 	glm::vec3 GetWorldLightPosition(int iLightIx) const;
 
+	void CreateTimer(const std::string &timerName, Framework::Timer::Type eType, float fDuration);
+	float GetTimerValue(const std::string &timerName) const;
+
 private:
 	typedef Framework::ConstVelLinearInterpolator<glm::vec3> LightInterpolator;
+	typedef std::map<std::string, Framework::Timer> ExtraTimerMap;
 
 	Framework::Timer m_keyLightTimer;
 	Framework::LinearInterpolator<glm::vec4> m_ambientInterpolator;
 
 	std::vector<LightInterpolator> m_lightPos;
 	std::vector<Framework::Timer> m_lightTimers;
-
+	ExtraTimerMap m_extraTimers;
 };
 
 #endif //LIGHTS_H

File Tut 12 Dynamic Range/Scene Lighting.cpp

 	GLuint theProgram;
 
 	GLuint modelToCameraMatrixUnif;
-
-	GLuint lightIntensityUnif;
-	GLuint ambientIntensityUnif;
-
 	GLuint normalModelToCameraMatrixUnif;
-	GLuint cameraSpaceLightPosUnif;
-	GLuint lightAttenuationUnif;
-	GLuint shininessFactorUnif;
-	GLuint baseDiffuseColorUnif;
 };
 
 struct UnlitProgData
 	LM_VERT_COLOR_DIFFUSE_SPECULAR = 0,
 	LM_VERT_COLOR_DIFFUSE,
 
+	LM_DIFFUSE_SPECULAR,
+	LM_DIFFUSE,
+
 	LM_MAX_LIGHTING_MODEL,
 };
 
 {
 	{"PCN.vert", "DiffuseSpecular.frag"},
 	{"PCN.vert", "DiffuseOnly.frag"},
+
+	{"PN.vert", "DiffuseSpecularMtl.frag"},
+	{"PN.vert", "DiffuseOnlyMtl.frag"},
 };
 
 UnlitProgData g_Unlit;
 LightManager g_lights;
 
 Framework::RadiusDef radiusDef = {50.0f, 3.0f, 80.0f, 4.0f, 1.0f};
-glm::vec3 objectCenter = glm::vec3(-50.0f, 0.0f, 50.0f);
+glm::vec3 objectCenter = glm::vec3(0.0f, 50.0f, 0.0f);
 
 Framework::MousePole g_mousePole(objectCenter, radiusDef);
 
 	}
 }
 
-Framework::Mesh *g_pTerrainMesh = NULL;
-Framework::Mesh *g_pLightMesh = NULL;
-
 struct MaterialBlock
 {
 	glm::vec4 diffuseColor;
 	glm::mat4 cameraToClipMatrix;
 };
 
+//One for the ground, and one for each of the 5 objects.
+const int MATERIAL_COUNT = 6;
+
+void GetMaterials(std::vector<MaterialBlock> &materials)
+{
+	materials.resize(MATERIAL_COUNT);
+
+	//Ground
+	materials[0].diffuseColor = glm::vec4(1.0f);
+	materials[0].specularColor = glm::vec4(0.5f, 0.5f, 0.5f, 1.0f);
+	materials[0].specularShininess = 0.6f;
+
+	//Tetrahedron
+	materials[1].diffuseColor = glm::vec4(1.0f);
+	materials[1].specularColor = glm::vec4(0.5f, 0.5f, 0.5f, 1.0f);
+	materials[1].specularShininess = 0.05f;
+
+	//Monolith
+	materials[2].diffuseColor = glm::vec4(1.0f);
+	materials[2].specularColor = glm::vec4(0.5f, 0.5f, 0.5f, 1.0f);
+	materials[2].specularShininess = 0.6f;
+
+	//Cube
+	materials[3].diffuseColor = glm::vec4(1.0f);
+	materials[3].specularColor = glm::vec4(0.5f, 0.5f, 0.5f, 1.0f);
+	materials[3].specularShininess = 0.6f;
+
+	//Cylinder
+	materials[4].diffuseColor = glm::vec4(1.0f);
+	materials[4].specularColor = glm::vec4(0.5f, 0.5f, 0.5f, 1.0f);
+	materials[4].specularShininess = 0.6f;
+
+	//Sphere
+	materials[5].diffuseColor = glm::vec4(1.0f);
+	materials[5].specularColor = glm::vec4(0.5f, 0.5f, 0.5f, 1.0f);
+	materials[5].specularShininess = 0.6f;
+}
+
 GLuint g_lightUniformBuffer;
 GLuint g_materialUniformBuffer;
 GLuint g_projectionUniformBuffer;
 
+GLuint g_sizeMaterialBlock = 0;
+
+void GenerateMaterialBuffer()
+{
+	//Align the size of each MaterialBlock to the uniform buffer alignment.
+	int uniformBufferAlignSize = 0;
+	glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniformBufferAlignSize);
+
+	g_sizeMaterialBlock = sizeof(MaterialBlock);
+	g_sizeMaterialBlock += uniformBufferAlignSize -
+		(g_sizeMaterialBlock % uniformBufferAlignSize);
+
+	int sizeMaterialUniformBuffer = g_sizeMaterialBlock * MATERIAL_COUNT;
+
+	std::vector<MaterialBlock> materials;
+	GetMaterials(materials);
+	assert(materials.size() == MATERIAL_COUNT);
+
+	std::vector<GLubyte> mtlBuffer;
+	mtlBuffer.resize(sizeMaterialUniformBuffer, 0);
+
+	GLubyte *bufferPtr = &mtlBuffer[0];
+
+	for(size_t mtl = 0; mtl < materials.size(); ++mtl)
+		memcpy(bufferPtr + (mtl * g_sizeMaterialBlock), &materials[mtl], sizeof(MaterialBlock));
+
+	glGenBuffers(1, &g_materialUniformBuffer);
+	glBindBuffer(GL_UNIFORM_BUFFER, g_materialUniformBuffer);
+	glBufferData(GL_UNIFORM_BUFFER, sizeMaterialUniformBuffer, bufferPtr, GL_STATIC_DRAW);
+}
+
+Framework::Mesh *g_pTerrainMesh = NULL;
+Framework::Mesh *g_pCubeMesh = NULL;
+Framework::Mesh *g_pTetraMesh = NULL;
+Framework::Mesh *g_pCylMesh = NULL;
+Framework::Mesh *g_pSphereMesh = NULL;
+
 //Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
 void init()
 {
 	try
 	{
 		g_pTerrainMesh = new Framework::Mesh("Ground.xml");
-		g_pLightMesh = new Framework::Mesh("UnitCube.xml");
+		g_pCubeMesh = new Framework::Mesh("UnitCube.xml");
+		g_pTetraMesh = new Framework::Mesh("UnitTetrahedron.xml");
+		g_pCylMesh = new Framework::Mesh("UnitCylinder.xml");
+		g_pSphereMesh = new Framework::Mesh("UnitSphere.xml");
 	}
 	catch(std::exception &except)
 	{
 		printf(except.what());
+		throw;
 	}
 
+	g_lights.CreateTimer("tetra", Framework::Timer::TT_LOOP, 2.5f);
+
  	glutMouseFunc(MouseButton);
  	glutMotionFunc(MouseMotion);
 	glutMouseWheelFunc(MouseWheel);
 	glBindBuffer(GL_UNIFORM_BUFFER, g_projectionUniformBuffer);
 	glBufferData(GL_UNIFORM_BUFFER, sizeof(ProjectionBlock), NULL, GL_DYNAMIC_DRAW);
 
-	MaterialBlock mtlData;
-	mtlData.diffuseColor = glm::vec4(1.0f);
-	mtlData.specularColor = glm::vec4(0.05f, 0.05f, 0.05f, 1.0f);
-	mtlData.specularShininess = 0.6f;
-
-	glGenBuffers(1, &g_materialUniformBuffer);
-	glBindBuffer(GL_UNIFORM_BUFFER, g_materialUniformBuffer);
-	glBufferData(GL_UNIFORM_BUFFER, sizeof(MaterialBlock), &mtlData, GL_STATIC_DRAW);
-
+	//Bind the static buffers.
 	glBindBufferRange(GL_UNIFORM_BUFFER, g_iLightBlockIndex, g_lightUniformBuffer,
 		0, sizeof(LightBlock));
 
 		0, sizeof(ProjectionBlock));
 
 	glBindBuffer(GL_UNIFORM_BUFFER, 0);
+
+	GenerateMaterialBuffer();
+
 }
 
 bool g_bDrawCameraPos = false;
 
+void DrawObject(const Framework::Mesh *pMesh, 
+				const ProgramData &prog, int mtlIx,
+				const Framework::MatrixStack &modelMatrix)
+{
+	glBindBufferRange(GL_UNIFORM_BUFFER, g_iMaterialBlockIndex, g_materialUniformBuffer,
+		mtlIx * g_sizeMaterialBlock, sizeof(MaterialBlock));
+
+	glm::mat3 normMatrix(modelMatrix.Top());
+	normMatrix = glm::transpose(glm::inverse(normMatrix));
+
+	glUseProgram(prog.theProgram);
+	glUniformMatrix4fv(prog.modelToCameraMatrixUnif, 1, GL_FALSE,
+		glm::value_ptr(modelMatrix.Top()));
+
+	glUniformMatrix3fv(prog.normalModelToCameraMatrixUnif, 1, GL_FALSE,
+		glm::value_ptr(normMatrix));
+	pMesh->Render();
+	glUseProgram(0);
+
+	glBindBufferRange(GL_UNIFORM_BUFFER, g_iMaterialBlockIndex, 0, 0, 0);
+}
+
+void DrawObject(const Framework::Mesh *pMesh, const std::string &meshName, 
+				const ProgramData &prog, int mtlIx,
+				const Framework::MatrixStack &modelMatrix)
+{
+	glBindBufferRange(GL_UNIFORM_BUFFER, g_iMaterialBlockIndex, g_materialUniformBuffer,
+		mtlIx * g_sizeMaterialBlock, sizeof(MaterialBlock));
+
+	glm::mat3 normMatrix(modelMatrix.Top());
+	normMatrix = glm::transpose(glm::inverse(normMatrix));
+
+	glUseProgram(prog.theProgram);
+	glUniformMatrix4fv(prog.modelToCameraMatrixUnif, 1, GL_FALSE,
+		glm::value_ptr(modelMatrix.Top()));
+
+	glUniformMatrix3fv(prog.normalModelToCameraMatrixUnif, 1, GL_FALSE,
+		glm::value_ptr(normMatrix));
+	pMesh->Render(meshName);
+	glUseProgram(0);
+
+	glBindBufferRange(GL_UNIFORM_BUFFER, g_iMaterialBlockIndex, 0, 0, 0);
+}
+
 //Called to update the display.
 //You should call glutSwapBuffers after all of your rendering to display what you rendered.
 //If you need continuous updates of the screen, call glutPostRedisplay() at the end of the function.
 	glClearDepth(1.0f);
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
-	if(g_pLightMesh && g_pLightMesh)
+	Framework::MatrixStack modelMatrix;
+	modelMatrix.SetMatrix(g_mousePole.CalcMatrix());
+
+	const glm::mat4 &worldToCamMat = modelMatrix.Top();
+	LightBlock lightData = g_lights.GetLightPositions(worldToCamMat);
+
+	glBindBuffer(GL_UNIFORM_BUFFER, g_lightUniformBuffer);
+	glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(lightData), &lightData);
+	glBindBuffer(GL_UNIFORM_BUFFER, 0);
+
 	{
-		Framework::MatrixStack modelMatrix;
-		modelMatrix.SetMatrix(g_mousePole.CalcMatrix());
+		Framework::MatrixStackPusher push(modelMatrix);
 
-		ProgramData &prog = g_Programs[LM_VERT_COLOR_DIFFUSE_SPECULAR];
+		//Render the ground plane.
+		{
+			Framework::MatrixStackPusher push(modelMatrix);
+			modelMatrix.RotateX(-90);
 
-		const glm::mat4 &worldToCamMat = modelMatrix.Top();
-		LightBlock lightData = g_lights.GetLightPositions(worldToCamMat);
+			DrawObject(g_pTerrainMesh, g_Programs[LM_VERT_COLOR_DIFFUSE], 0,
+				modelMatrix);
+		}
 
-		glBindBuffer(GL_UNIFORM_BUFFER, g_lightUniformBuffer);
-		glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(lightData), &lightData);
-		glBindBuffer(GL_UNIFORM_BUFFER, 0);
+		//Render the tetrahedron object.
+		{
+			Framework::MatrixStackPusher push(modelMatrix);
+			modelMatrix.Translate(75.0f, 5.0f, 75.0f);
+			modelMatrix.RotateY(360.0f * g_lights.GetTimerValue("tetra"));
+			modelMatrix.Scale(10.0f, 10.0f, 10.0f);
+			modelMatrix.Translate(0.0f, sqrtf(2.0f), 0.0f);
+			modelMatrix.Rotate(glm::vec3(-0.707f, 0.0f, -0.707f), 54.735f);
 
+			DrawObject(g_pTetraMesh, "lit-color", g_Programs[LM_VERT_COLOR_DIFFUSE_SPECULAR],
+				1, modelMatrix);
+		}
+
+		//Render the monolith object.
+		{
+			Framework::MatrixStackPusher push(modelMatrix);
+			modelMatrix.Translate(88.0f, 5.0f, -80.0f);
+			modelMatrix.Scale(4.0f, 4.0f, 4.0f);
+			modelMatrix.Scale(4.0f, 9.0f, 1.0f);
+			modelMatrix.Translate(0.0f, 0.5f, 0.0f);
+
+			DrawObject(g_pCubeMesh, "lit", g_Programs[LM_DIFFUSE_SPECULAR],
+				2, modelMatrix);
+		}
+
+		//Render the cube object.
+		{
+			Framework::MatrixStackPusher push(modelMatrix);
+			modelMatrix.Translate(-52.5f, 14.0f, 65.0f);
+			modelMatrix.RotateZ(50.0f);
+			modelMatrix.RotateY(-10.0f);
+			modelMatrix.Scale(20.0f, 20.0f, 20.0f);
+
+			DrawObject(g_pCubeMesh, "lit-color", g_Programs[LM_VERT_COLOR_DIFFUSE_SPECULAR],
+				3, modelMatrix);
+		}
+
+		//Render the cylinder.
+		{
+			Framework::MatrixStackPusher push(modelMatrix);
+			modelMatrix.Translate(-7.0f, 30.0f, -14.0f);
+			modelMatrix.Scale(15.0f, 55.0f, 15.0f);
+			modelMatrix.Translate(0.0f, 0.5f, 0.0f);
+
+			DrawObject(g_pCylMesh, "lit-color", g_Programs[LM_VERT_COLOR_DIFFUSE_SPECULAR],
+				4, modelMatrix);
+		}
+
+		//Render the sphere.
+		{
+			Framework::MatrixStackPusher push(modelMatrix);
+			modelMatrix.Translate(-83.0f, 14.0f, -77.0f);
+			modelMatrix.Scale(20.0f, 20.0f, 20.0f);
+
+			DrawObject(g_pSphereMesh, "lit", g_Programs[LM_DIFFUSE_SPECULAR],
+				5, modelMatrix);
+		}
+
+		//Render the light
+		for(int light = 0; light < g_lights.GetNumberOfPointLights(); light++)
 		{
 			Framework::MatrixStackPusher push(modelMatrix);
 
-			//Render the ground plane.
-			{
-				glBindBufferRange(GL_UNIFORM_BUFFER, g_iMaterialBlockIndex, g_materialUniformBuffer,
-					0, sizeof(MaterialBlock));
+			modelMatrix.Translate(g_lights.GetWorldLightPosition(light));
 
-				Framework::MatrixStackPusher push(modelMatrix);
-				modelMatrix.RotateX(-90);
+			glUseProgram(g_Unlit.theProgram);
+			glUniformMatrix4fv(g_Unlit.modelToCameraMatrixUnif, 1, GL_FALSE,
+				glm::value_ptr(modelMatrix.Top()));
+			glUniform4f(g_Unlit.objectColorUnif, 0.8078f, 0.8706f, 0.9922f, 1.0f);
+			g_pCubeMesh->Render("flat");
+		}
 
-				glm::mat3 normMatrix(modelMatrix.Top());
-				normMatrix = glm::transpose(glm::inverse(normMatrix));
+		if(g_bDrawCameraPos)
+		{
+			Framework::MatrixStackPusher push(modelMatrix);
 
-				glUseProgram(prog.theProgram);
-				glUniformMatrix4fv(prog.modelToCameraMatrixUnif, 1, GL_FALSE,
-					glm::value_ptr(modelMatrix.Top()));
+			modelMatrix.SetIdentity();
+			modelMatrix.Translate(glm::vec3(0.0f, 0.0f, -g_mousePole.GetLookAtDistance()));
 
-				glUniformMatrix3fv(prog.normalModelToCameraMatrixUnif, 1, GL_FALSE,
-					glm::value_ptr(normMatrix));
-				g_pTerrainMesh->Render();
-				glUseProgram(0);
-
-				glBindBufferRange(GL_UNIFORM_BUFFER, g_iMaterialBlockIndex, 0, 0, 0);
-			}
-
-			//Render the light
-			for(int light = 0; light < g_lights.GetNumberOfPointLights(); light++)
-			{
-				Framework::MatrixStackPusher push(modelMatrix);
-
-				modelMatrix.Translate(g_lights.GetWorldLightPosition(light));
-
-				glUseProgram(g_Unlit.theProgram);
-				glUniformMatrix4fv(g_Unlit.modelToCameraMatrixUnif, 1, GL_FALSE,
-					glm::value_ptr(modelMatrix.Top()));
-				glUniform4f(g_Unlit.objectColorUnif, 0.8078f, 0.8706f, 0.9922f, 1.0f);
-				g_pLightMesh->Render("flat");
-			}
-
-			if(g_bDrawCameraPos)
-			{
-				Framework::MatrixStackPusher push(modelMatrix);
-
-				modelMatrix.SetIdentity();
-				modelMatrix.Translate(glm::vec3(0.0f, 0.0f, -g_mousePole.GetLookAtDistance()));
-
-				glDisable(GL_DEPTH_TEST);
-				glDepthMask(GL_FALSE);
-				glUseProgram(g_Unlit.theProgram);
-				glUniformMatrix4fv(g_Unlit.modelToCameraMatrixUnif, 1, GL_FALSE,
-					glm::value_ptr(modelMatrix.Top()));
-				glUniform4f(g_Unlit.objectColorUnif, 0.25f, 0.25f, 0.25f, 1.0f);
-				g_pLightMesh->Render("flat");
-				glDepthMask(GL_TRUE);
-				glEnable(GL_DEPTH_TEST);
-				glUniform4f(g_Unlit.objectColorUnif, 1.0f, 1.0f, 1.0f, 1.0f);
-				g_pLightMesh->Render("flat");
-			}
+			glDisable(GL_DEPTH_TEST);
+			glDepthMask(GL_FALSE);
+			glUseProgram(g_Unlit.theProgram);
+			glUniformMatrix4fv(g_Unlit.modelToCameraMatrixUnif, 1, GL_FALSE,
+				glm::value_ptr(modelMatrix.Top()));
+			glUniform4f(g_Unlit.objectColorUnif, 0.25f, 0.25f, 0.25f, 1.0f);
+			g_pCubeMesh->Render("flat");
+			glDepthMask(GL_TRUE);
+			glEnable(GL_DEPTH_TEST);
+			glUniform4f(g_Unlit.objectColorUnif, 1.0f, 1.0f, 1.0f, 1.0f);
+			g_pCubeMesh->Render("flat");
 		}
 	}
 
 	{
 	case 27:
 		delete g_pTerrainMesh;
-		delete g_pLightMesh;
+		delete g_pCubeMesh;
+		delete g_pTetraMesh;
+		delete g_pCylMesh;
+		delete g_pSphereMesh;
 		glutLeaveMainLoop();
 		break;
 		
 	case 'a': g_mousePole.OffsetTargetPos(Framework::MousePole::DIR_LEFT, 5.0f); break;
 	case 'e': g_mousePole.OffsetTargetPos(Framework::MousePole::DIR_UP, 5.0f); break;
 	case 'q': g_mousePole.OffsetTargetPos(Framework::MousePole::DIR_DOWN, 5.0f); break;
+
+	case 32:
+		printf("%f\n", 360.0f * g_lights.GetTimerValue("tetra"));
+		break;
 	}
 
 	glutPostRedisplay();

File Tut 12 Dynamic Range/data/DiffuseOnlyMtl.frag

+#version 330
+
+in vec3 vertexNormal;
+in vec3 cameraSpacePosition;
+
+out vec4 outputColor;
+
+layout(std140) uniform;
+
+uniform Material
+{
+	vec4 diffuseColor;
+	vec4 specularColor;
+	float specularShininess;
+} Mtl;
+
+struct PerLight
+{
+	vec4 cameraSpaceLightPos;
+	vec4 lightIntensity;
+};
+
+const int numberOfLights = 4;
+
+uniform Light
+{
+	vec4 ambientIntensity;
+	float lightAttenuation;
+	PerLight lights[numberOfLights];
+} Lgt;
+
+
+float CalcAttenuation(in vec3 cameraSpacePosition,
+	in vec3 cameraSpaceLightPos,
+	out vec3 lightDirection)
+{
+	vec3 lightDifference =  cameraSpaceLightPos - cameraSpacePosition;
+	float lightDistanceSqr = dot(lightDifference, lightDifference);
+	lightDirection = lightDifference * inversesqrt(lightDistanceSqr);
+	
+	return (1 / ( 1.0 + Lgt.lightAttenuation * Lgt.lightAttenuation
+		* sqrt(lightDistanceSqr)));
+}
+
+vec4 ComputeLighting(in PerLight lightData)
+{
+	vec3 lightDir;
+	vec4 lightIntensity;
+	if(lightData.cameraSpaceLightPos.w == 0.0)
+	{
+		lightDir = vec3(lightData.cameraSpaceLightPos);
+		lightIntensity = lightData.lightIntensity;
+	}
+	else
+	{
+		float atten = CalcAttenuation(cameraSpacePosition,
+			lightData.cameraSpaceLightPos.xyz, lightDir);
+		lightIntensity = atten * lightData.lightIntensity;
+	}
+	
+	vec3 surfaceNormal = normalize(vertexNormal);
+	float cosAngIncidence = dot(surfaceNormal, lightDir);
+	cosAngIncidence = clamp(cosAngIncidence, 0, 1);
+	
+	vec4 lighting = Mtl.diffuseColor * lightIntensity * cosAngIncidence;
+	
+	return lighting;
+}
+
+void main()
+{
+	vec4 accumLighting = Mtl.diffuseColor * Lgt.ambientIntensity;
+	for(int light = 0; light < numberOfLights; light++)
+	{
+		accumLighting += ComputeLighting(Lgt.lights[light]);
+	}
+	
+	outputColor = accumLighting;
+}

File Tut 12 Dynamic Range/data/DiffuseSpecularMtl.frag

+#version 330
+
+in vec3 vertexNormal;
+in vec3 cameraSpacePosition;
+
+out vec4 outputColor;
+
+layout(std140) uniform;
+
+uniform Material
+{
+	vec4 diffuseColor;
+	vec4 specularColor;
+	float specularShininess;
+} Mtl;
+
+struct PerLight
+{
+	vec4 cameraSpaceLightPos;
+	vec4 lightIntensity;
+};
+
+const int numberOfLights = 4;
+
+uniform Light
+{
+	vec4 ambientIntensity;
+	float lightAttenuation;
+	PerLight lights[numberOfLights];
+} Lgt;
+
+
+float CalcAttenuation(in vec3 cameraSpacePosition,
+	in vec3 cameraSpaceLightPos,
+	out vec3 lightDirection)
+{
+	vec3 lightDifference =  cameraSpaceLightPos - cameraSpacePosition;
+	float lightDistanceSqr = dot(lightDifference, lightDifference);
+	lightDirection = lightDifference * inversesqrt(lightDistanceSqr);
+	
+	return (1 / ( 1.0 + Lgt.lightAttenuation * Lgt.lightAttenuation
+		* sqrt(lightDistanceSqr)));
+}
+
+vec4 ComputeLighting(in PerLight lightData)
+{
+	vec3 lightDir;
+	vec4 lightIntensity;
+	if(lightData.cameraSpaceLightPos.w == 0.0)
+	{
+		lightDir = vec3(lightData.cameraSpaceLightPos);
+		lightIntensity = lightData.lightIntensity;
+	}
+	else
+	{
+		float atten = CalcAttenuation(cameraSpacePosition,
+			lightData.cameraSpaceLightPos.xyz, lightDir);
+		lightIntensity = atten * lightData.lightIntensity;
+	}
+	
+	vec3 surfaceNormal = normalize(vertexNormal);
+	float cosAngIncidence = dot(surfaceNormal, lightDir);
+	cosAngIncidence = clamp(cosAngIncidence, 0, 1);
+	
+	vec3 viewDirection = normalize(-cameraSpacePosition);
+	
+	vec3 halfAngle = normalize(lightDir + viewDirection);
+	float angleNormalHalf = acos(dot(halfAngle, surfaceNormal));
+	float exponent = angleNormalHalf / Mtl.specularShininess;
+	exponent = -(exponent * exponent);
+	float gaussianTerm = exp(exponent);
+
+	gaussianTerm = cosAngIncidence != 0.0 ? gaussianTerm : 0.0;
+	
+	vec4 lighting = Mtl.diffuseColor * lightIntensity * cosAngIncidence;
+	lighting += Mtl.specularColor * lightIntensity * gaussianTerm;
+	
+	return lighting;
+}
+
+void main()
+{
+	vec4 accumLighting = Mtl.diffuseColor * Lgt.ambientIntensity;
+	for(int light = 0; light < numberOfLights; light++)
+	{
+		accumLighting += ComputeLighting(Lgt.lights[light]);
+	}
+	
+	outputColor = accumLighting;
+}

File Tut 12 Dynamic Range/data/GenCube.lua

 	vmath.vec3(-0.5,  0.5, -0.5),
 };
 
-local tints =
+local normals =
 {
-	vmath.vec4(1.0, 1.0, 1.0, 1.0),
-	vmath.vec4(1.0, 1.0, 1.0, 1.0),
-	vmath.vec4(1.0, 1.0, 1.0, 1.0),
-	vmath.vec4(1.0, 1.0, 1.0, 1.0),
+	--Front
+	vmath.vec3(0.0,  0.0,  1.0),
+	vmath.vec3(0.0,  0.0,  1.0),
+	vmath.vec3(0.0,  0.0,  1.0),
+	vmath.vec3(0.0,  0.0,  1.0),
 
-	vmath.vec4(0.75, 0.75, 0.75, 1.0),
-	vmath.vec4(0.75, 0.75, 0.75, 1.0),
-	vmath.vec4(0.75, 0.75, 0.75, 1.0),
-	vmath.vec4(0.75, 0.75, 0.75, 1.0),
+	--Top
+	vmath.vec3(0.0,  1.0,  0.0),
+	vmath.vec3(0.0,  1.0,  0.0),
+	vmath.vec3(0.0,  1.0,  0.0),
+	vmath.vec3(0.0,  1.0,  0.0),
 
-	vmath.vec4(0.5, 0.5, 0.5, 1.0),
-	vmath.vec4(0.5, 0.5, 0.5, 1.0),
-	vmath.vec4(0.5, 0.5, 0.5, 1.0),
-	vmath.vec4(0.5, 0.5, 0.5, 1.0),
+	--Left
+	vmath.vec3(1.0,  0.0,  0.0),
+	vmath.vec3(1.0,  0.0,  0.0),
+	vmath.vec3(1.0,  0.0,  0.0),
+	vmath.vec3(1.0,  0.0,  0.0),
 
-	vmath.vec4(1.0, 1.0, 1.0, 1.0),
-	vmath.vec4(1.0, 1.0, 1.0, 1.0),
-	vmath.vec4(1.0, 1.0, 1.0, 1.0),
-	vmath.vec4(1.0, 1.0, 1.0, 1.0),
+	--Back
+	vmath.vec3(0.0,  0.0, -1.0),
+	vmath.vec3(0.0,  0.0, -1.0),
+	vmath.vec3(0.0,  0.0, -1.0),
+	vmath.vec3(0.0,  0.0, -1.0),
 
-	vmath.vec4(0.75, 0.75, 0.75, 1.0),
-	vmath.vec4(0.75, 0.75, 0.75, 1.0),
-	vmath.vec4(0.75, 0.75, 0.75, 1.0),
-	vmath.vec4(0.75, 0.75, 0.75, 1.0),
+	--Bottom
+	vmath.vec3(0.0, -1.0,  0.0),
+	vmath.vec3(0.0, -1.0,  0.0),
+	vmath.vec3(0.0, -1.0,  0.0),
+	vmath.vec3(0.0, -1.0,  0.0),
 
-	vmath.vec4(0.5, 0.5, 0.5, 1.0),
-	vmath.vec4(0.5, 0.5, 0.5, 1.0),
-	vmath.vec4(0.5, 0.5, 0.5, 1.0),
-	vmath.vec4(0.5, 0.5, 0.5, 1.0),
+	--Right
+	vmath.vec3(-1.0,  0.0,  0.0),
+	vmath.vec3(-1.0,  0.0,  0.0),
+	vmath.vec3(-1.0,  0.0,  0.0),
+	vmath.vec3(-1.0,  0.0,  0.0),
 }
 
 local colors =
 			writer:AddAttribute("size", "4");
 			writer:AddText(GenStringFromArray(colors));
 		writer:PopElement();
+		writer:PushElement("attribute");
+			writer:AddAttribute("index", "2");
+			writer:AddAttribute("type", "float");
+			writer:AddAttribute("size", "3");
+			writer:AddText(GenStringFromArray(normals));
+		writer:PopElement();
+		writer:PushElement("vao");
+			writer:AddAttribute("name", "lit");
+			writer:PushElement("source"); writer:AddAttribute("attrib", "0"); writer:PopElement();
+			writer:PushElement("source"); writer:AddAttribute("attrib", "2"); writer:PopElement();
+		writer:PopElement();
+		writer:PushElement("vao");
+			writer:AddAttribute("name", "lit-color");
+			writer:PushElement("source"); writer:AddAttribute("attrib", "0"); writer:PopElement();
+			writer:PushElement("source"); writer:AddAttribute("attrib", "1"); writer:PopElement();
+			writer:PushElement("source"); writer:AddAttribute("attrib", "2"); writer:PopElement();
+		writer:PopElement();
 		writer:PushElement("vao");
 			writer:AddAttribute("name", "color");
 			writer:PushElement("source"); writer:AddAttribute("attrib", "0"); writer:PopElement();

File Tut 12 Dynamic Range/data/GenCylinder.lua

+require "XmlWriter"
+require "vmath"
+
+local function GenStringFromArray(theArray)
+	local array = {" "}
+	for i, vector in ipairs(theArray) do
+		array[#array + 1] = "        " .. table.concat(vector, " ");
+	end
+	
+	return table.concat(array, "\n");
+end
+
+local positions = {};
+local colors = {};
+local normals = {};
+local topFan = {};
+local botFan = {};
+local cylStrip = {};
+
+local iSegCount, iColorRepeatCount = ...;
+iSegCount = iSegCount or 30;
+iColorRepeatCount = iColorRepeatCount or 3;
+
+local iAngle = 3.14159 * 2.0 / iSegCount;
+local iColorCycleAngle = 3.14159 * 2.0 / iColorRepeatCount;
+local highColor = vmath.vec4(0.9, 0.5, 0.5, 1.0);
+local lowColor = vmath.vec4(0.5, 0.1, 0.1, 1.0)
+
+--Compute caps
+positions[#positions + 1] = vmath.vec3(0.0, 0.5, 0.0);
+colors[#colors + 1] = vmath.vec4(1.0, 1.0, 1.0, 1.0);
+normals[#normals + 1] = vmath.vec3(0.0, 1.0, 0.0);
+topFan[#topFan + 1] = 0;
+botFan[#botFan + 1] = (iSegCount * 2) + 1;
+
+local firstSideIx = #positions;
+
+for iSeg = 0, (iSegCount - 1), 1 do
+	local iCurrAngle = iSeg * iAngle;
+
+	positions[#positions + 1] =
+		vmath.vec3(0.5 * math.cos(iCurrAngle), 0.5, 0.5 * math.sin(iCurrAngle));
+	positions[#positions + 1] =
+		vmath.vec3(0.5 * math.cos(iCurrAngle), -0.5, 0.5 * math.sin(iCurrAngle));
+
+	normals[#normals + 1] = vmath.vec3(0.0, 1.0, 0.0);
+	normals[#normals + 1] = vmath.vec3(0.0, -1.0, 0.0);
+		
+	local clrDist = math.mod(iCurrAngle, iColorCycleAngle) / iColorCycleAngle;
+	if(clrDist > 0.5) then
+		local interp = (clrDist - 0.5) * 2;
+		colors[#colors + 1] = (interp * highColor) +
+			((1 - interp) * lowColor);
+	else
+		local interp = clrDist * 2;
+		colors[#colors + 1] = (interp * lowColor) +
+			((1 - interp) * highColor);
+	end
+	
+	colors[#colors + 1] = colors[#colors];
+
+	topFan[#topFan + 1] = 1 + (iSeg * 2);
+	botFan[#botFan + 1] = 1 + (((iSegCount - iSeg) * 2) - 1);
+end
+
+topFan[#topFan + 1] = topFan[2];
+botFan[#botFan + 1] = botFan[2];
+
+positions[#positions + 1] = vmath.vec3(0.0, -0.5, 0.0);
+colors[#colors + 1] = vmath.vec4(1.0, 1.0, 1.0, 1.0);
+normals[#normals + 1] = vmath.vec3(0.0, -1.0, 0.0);
+
+--Compute sides.
+for iSeg = 0, (iSegCount - 1), 1 do
+	local iCurrAngle = iSeg * iAngle;
+
+	positions[#positions + 1] =
+		vmath.vec3(0.5 * math.cos(iCurrAngle), 0.5, 0.5 * math.sin(iCurrAngle));
+	positions[#positions + 1] =
+		vmath.vec3(0.5 * math.cos(iCurrAngle), -0.5, 0.5 * math.sin(iCurrAngle));
+
+	normals[#normals + 1] = vmath.vec3(math.cos(iCurrAngle), 0, math.sin(iCurrAngle));
+	normals[#normals + 1] = normals[#normals];
+		
+	local clrDist = math.mod(iCurrAngle, iColorCycleAngle) / iColorCycleAngle;
+	if(clrDist > 0.5) then
+		local interp = (clrDist - 0.5) * 2;
+		colors[#colors + 1] = (interp * highColor) +
+			((1 - interp) * lowColor);
+	else
+		local interp = clrDist * 2;
+		colors[#colors + 1] = (interp * lowColor) +
+			((1 - interp) * highColor);
+	end
+	
+	colors[#colors + 1] = colors[#colors];
+
+	cylStrip[#cylStrip + 1] = #positions - 2;
+	cylStrip[#cylStrip + 1] = #positions - 1;
+end
+
+cylStrip[#cylStrip + 1] = cylStrip[1];
+cylStrip[#cylStrip + 1] = cylStrip[2];
+
+do
+	local writer = XmlWriter.XmlWriter("UnitCylinder.xml");
+	writer:AddPI("oxygen", [[RNGSchema="../../Documents/meshFormat.rnc" type="compact"]]);
+	writer:PushElement("mesh", "http://www.arcsynthesis.com/gltut/mesh");
+		writer:PushElement("attribute");
+			writer:AddAttribute("index", "0");
+			writer:AddAttribute("type", "float");
+			writer:AddAttribute("size", "3");
+			writer:AddText(GenStringFromArray(positions));
+		writer:PopElement();
+		writer:PushElement("attribute");
+			writer:AddAttribute("index", "1");
+			writer:AddAttribute("type", "float");
+			writer:AddAttribute("size", "4");
+			writer:AddText(GenStringFromArray(colors));
+		writer:PopElement();
+		writer:PushElement("attribute");
+			writer:AddAttribute("index", "2");
+			writer:AddAttribute("type", "float");
+			writer:AddAttribute("size", "3");
+			writer:AddText(GenStringFromArray(normals));
+		writer:PopElement();
+		writer:PushElement("vao");
+			writer:AddAttribute("name", "lit-color");
+			writer:PushElement("source"); writer:AddAttribute("attrib", "0"); writer:PopElement();
+			writer:PushElement("source"); writer:AddAttribute("attrib", "1"); writer:PopElement();
+			writer:PushElement("source"); writer:AddAttribute("attrib", "2"); writer:PopElement();
+		writer:PopElement();
+		writer:PushElement("vao");
+			writer:AddAttribute("name", "lit");
+			writer:PushElement("source"); writer:AddAttribute("attrib", "0"); writer:PopElement();
+			writer:PushElement("source"); writer:AddAttribute("attrib", "2"); writer:PopElement();
+		writer:PopElement();
+		writer:PushElement("vao");
+			writer:AddAttribute("name", "color");
+			writer:PushElement("source"); writer:AddAttribute("attrib", "0"); writer:PopElement();
+			writer:PushElement("source"); writer:AddAttribute("attrib", "1"); writer:PopElement();
+		writer:PopElement();
+		writer:PushElement("indices");
+			writer:AddAttribute("cmd", "tri-fan");
+			writer:AddAttribute("type", "ushort");
+			writer:AddText(table.concat(topFan, " "));
+		writer:PopElement();
+		writer:PushElement("indices");
+			writer:AddAttribute("cmd", "tri-fan");
+			writer:AddAttribute("type", "ushort");
+			writer:AddText(table.concat(botFan, " "));
+		writer:PopElement();
+		writer:PushElement("indices");
+			writer:AddAttribute("cmd", "tri-strip");
+			writer:AddAttribute("type", "ushort");
+			writer:AddText(table.concat(cylStrip, " "));
+		writer:PopElement();
+	writer:PopElement();
+	writer:Close();
+end

File Tut 12 Dynamic Range/data/GenSphere.lua

 local restartIndex = 65535;
 
 local iSegCount, iColorRepeatCount, iRingCount = ...;
-iSegCount = iSegCount or 10;
+iSegCount = iSegCount or 15;
 iColorRepeatCount = iColorRepeatCount or 3;
-iRingCount = iRingCount or 5;
+iRingCount = iRingCount or 8;
 
 local rhoAngle = math.pi * 2.0 / iSegCount;
 local thetaAngle = math.pi / (iRingCount + 1);
 			writer:AddText(GenStringFromArray(normals));
 		writer:PopElement();
 		writer:PushElement("vao");
-			writer:AddAttribute("name", "tint");
+			writer:AddAttribute("name", "lit-color");
 			writer:PushElement("source"); writer:AddAttribute("attrib", "0"); writer:PopElement();
 			writer:PushElement("source"); writer:AddAttribute("attrib", "1"); writer:PopElement();
 			writer:PushElement("source"); writer:AddAttribute("attrib", "2"); writer:PopElement();
 		writer:PopElement();
 		writer:PushElement("vao");
-			writer:AddAttribute("name", "flat");
+			writer:AddAttribute("name", "lit");
 			writer:PushElement("source"); writer:AddAttribute("attrib", "0"); writer:PopElement();
 			writer:PushElement("source"); writer:AddAttribute("attrib", "2"); writer:PopElement();
 		writer:PopElement();
 		writer:PushElement("vao");
-			writer:AddAttribute("name", "tint-unlit");
+			writer:AddAttribute("name", "color");
 			writer:PushElement("source"); writer:AddAttribute("attrib", "0"); writer:PopElement();
 			writer:PushElement("source"); writer:AddAttribute("attrib", "1"); writer:PopElement();
 		writer:PopElement();

File Tut 12 Dynamic Range/data/GenTetrahedron.lua

+require "XmlWriter"
+require "vmath"
+
+local function GenStringFromArray(theArray, bAsInt)
+	local array = {" "}
+	for i, vector in ipairs(theArray) do
+		local elements = vector;
+		if(bAsInt) then
+			elements = {};
+			for i, value in ipairs(vector) do
+				elements[#elements + 1] = string.format("%i", value);
+			end
+		end
+		
+		array[#array + 1] = "        " .. table.concat(vector, " ");
+	end
+	
+	return table.concat(array, "\n");
+end
+
+local positions =
+{
+	vmath.vec3( 1.0,  1.0,  1.0),
+	vmath.vec3(-1.0, -1.0,  1.0),
+	vmath.vec3(-1.0,  1.0, -1.0),
+	
+	vmath.vec3(-1.0, -1.0,  1.0),
+	vmath.vec3( 1.0,  1.0,  1.0),
+	vmath.vec3( 1.0, -1.0, -1.0),
+
+	vmath.vec3(-1.0,  1.0, -1.0),
+	vmath.vec3( 1.0, -1.0, -1.0),
+	vmath.vec3( 1.0,  1.0,  1.0),
+
+	vmath.vec3( 1.0, -1.0, -1.0),
+	vmath.vec3(-1.0,  1.0, -1.0),
+	vmath.vec3(-1.0, -1.0,  1.0),
+	
+};
+
+local normals = {}
+
+for i = 1, #positions, 3 do
+	local vFirst = positions[i + 1] - positions[i];
+	local vSecond = positions[i + 2] - positions[i];
+	local normal = vmath.norm(vSecond:cross(vFirst));
+	normals[#normals + 1] = normal;
+	normals[#normals + 1] = normal;
+	normals[#normals + 1] = normal;
+end
+
+local colors =
+{
+	vmath.vec4(0.25, 1.0, 0.25, 1.0),
+	vmath.vec4(0.25, 1.0, 0.25, 1.0),
+	vmath.vec4(0.25, 1.0, 0.25, 1.0),
+	
+	vmath.vec4(0.5, 0.5, 1.0, 1.0),
+	vmath.vec4(0.5, 0.5, 1.0, 1.0),
+	vmath.vec4(0.5, 0.5, 1.0, 1.0),
+	
+	vmath.vec4(1.0, 0.0, 0.0, 1.0),
+	vmath.vec4(1.0, 0.0, 0.0, 1.0),
+	vmath.vec4(1.0, 0.0, 0.0, 1.0),
+	
+	vmath.vec4(0.0, 0.0, 0.0, 1.0),
+	vmath.vec4(0.0, 0.0, 0.0, 1.0),
+	vmath.vec4(0.0, 0.0, 0.0, 1.0),
+}
+
+do
+	local writer = XmlWriter.XmlWriter("UnitTetrahedron.xml");
+	writer:AddPI("oxygen", [[RNGSchema="../../Documents/meshFormat.rnc" type="compact"]]);
+	writer:PushElement("mesh", "http://www.arcsynthesis.com/gltut/mesh");
+		writer:PushElement("attribute");
+			writer:AddAttribute("index", "0");
+			writer:AddAttribute("type", "float");
+			writer:AddAttribute("size", "3");
+			writer:AddText(GenStringFromArray(positions));
+		writer:PopElement();
+		writer:PushElement("attribute");
+			writer:AddAttribute("index", "1");
+			writer:AddAttribute("type", "float");
+			writer:AddAttribute("size", "4");
+			writer:AddText(GenStringFromArray(colors));
+		writer:PopElement();
+		writer:PushElement("attribute");
+			writer:AddAttribute("index", "2");
+			writer:AddAttribute("type", "float");
+			writer:AddAttribute("size", "3");
+			writer:AddText(GenStringFromArray(normals));
+		writer:PopElement();
+		writer:PushElement("vao");
+			writer:AddAttribute("name", "lit");
+			writer:PushElement("source"); writer:AddAttribute("attrib", "0"); writer:PopElement();
+			writer:PushElement("source"); writer:AddAttribute("attrib", "2"); writer:PopElement();
+		writer:PopElement();
+		writer:PushElement("vao");
+			writer:AddAttribute("name", "lit-color");
+			writer:PushElement("source"); writer:AddAttribute("attrib", "0"); writer:PopElement();
+			writer:PushElement("source"); writer:AddAttribute("attrib", "1"); writer:PopElement();
+			writer:PushElement("source"); writer:AddAttribute("attrib", "2"); writer:PopElement();
+		writer:PopElement();
+		writer:PushElement("vao");
+			writer:AddAttribute("name", "color");
+			writer:PushElement("source"); writer:AddAttribute("attrib", "0"); writer:PopElement();
+			writer:PushElement("source"); writer:AddAttribute("attrib", "1"); writer:PopElement();
+		writer:PopElement();
+		writer:PushElement("vao");
+			writer:AddAttribute("name", "flat");
+			writer:PushElement("source"); writer:AddAttribute("attrib", "0"); writer:PopElement();
+		writer:PopElement();
+		writer:PushElement("arrays");
+			writer:AddAttribute("cmd", "triangles");
+			writer:AddAttribute("start", "0");
+			writer:AddAttribute("count", tostring(#positions));
+		writer:PopElement();
+	writer:PopElement();
+	writer:Close();
+end

File Tut 12 Dynamic Range/data/PN.vert

+#version 330
+
+layout(location = 0) in vec3 position;
+layout(location = 2) in vec3 normal;
+
+out vec3 vertexNormal;
+out vec3 cameraSpacePosition;
+
+uniform Projection
+{
+	mat4 cameraToClipMatrix;
+};
+
+uniform mat4 modelToCameraMatrix;
+uniform mat3 normalModelToCameraMatrix;
+
+void main()
+{
+	vec4 tempCamPosition = (modelToCameraMatrix * vec4(position, 1.0));
+	gl_Position = cameraToClipMatrix * tempCamPosition;
+
+	vertexNormal = normalize(normalModelToCameraMatrix * normal);
+	cameraSpacePosition = vec3(tempCamPosition);
+}

File Tut 12 Dynamic Range/data/UnitCube.xml

         1 0 1 1
         1 0 1 1
         1 0 1 1</attribute>
+	<attribute index="2" type="float" size="3" > 
+        0 0 1
+        0 0 1
+        0 0 1
+        0 0 1
+        0 1 0
+        0 1 0
+        0 1 0
+        0 1 0
+        1 0 0
+        1 0 0
+        1 0 0
+        1 0 0
+        0 0 -1
+        0 0 -1
+        0 0 -1
+        0 0 -1
+        0 -1 0
+        0 -1 0
+        0 -1 0
+        0 -1 0
+        -1 0 0
+        -1 0 0
+        -1 0 0
+        -1 0 0</attribute>
+	<vao name="lit" >
+		<source attrib="0" />
+		<source attrib="2" />
+	</vao>
+	<vao name="lit-color" >
+		<source attrib="0" />
+		<source attrib="1" />
+		<source attrib="2" />
+	</vao>
 	<vao name="color" >
 		<source attrib="0" />
 		<source attrib="1" />

File Tut 12 Dynamic Range/data/UnitCylinder.xml

+<?xml version="1.0" encoding="UTF-8"?>
+<?oxygen RNGSchema="../../Documents/meshFormat.rnc" type="compact"?>
+
+<mesh xmlns="http://www.arcsynthesis.com/gltut/mesh" >
+	<attribute index="0" type="float" size="3" > 
+        0 0.5 0
+        0.5 0.5 0
+        0.5 -0.5 0
+        0.48907381875731 0.5 0.1039557588888
+        0.48907381875731 -0.5 0.1039557588888
+        0.45677280077542 0.5 0.20336815992623
+        0.45677280077542 -0.5 0.20336815992623
+        0.40450865316151 0.5 0.29389241146627
+        0.40450865316151 -0.5 0.29389241146627
+        0.33456556611288 0.5 0.37157217599218
+        0.33456556611288 -0.5 0.37157217599218
+        0.2500003830126 0.5 0.43301248075957
+        0.2500003830126 -0.5 0.43301248075957
+        0.15450900193016 0.5 0.47552809414644
+        0.15450900193016 -0.5 0.47552809414644
+        0.052264847412855 0.5 0.49726088296277
+        0.052264847412855 -0.5 0.49726088296277
+        -0.052263527886268 0.5 0.49726102165048
+        -0.052263527886268 -0.5 0.49726102165048
+        -0.15450774007312 0.5 0.47552850414828
+        -0.15450774007312 -0.5 0.47552850414828
+        -0.24999923397422 0.5 0.43301314415651
+        -0.24999923397422 -0.5 0.43301314415651
+        -0.33456458011157 0.5 0.37157306379065
+        -0.33456458011157 -0.5 0.37157306379065
+        -0.40450787329018 0.5 0.29389348486527
+        -0.40450787329018 -0.5 0.29389348486527
+        -0.45677226111814 0.5 0.20336937201315
+        -0.45677226111814 -0.5 0.20336937201315
+        -0.48907354289964 0.5 0.10395705668972
+        -0.48907354289964 -0.5 0.10395705668972
+        -0.49999999999824 0.5 1.3267948966764e-006
+        -0.49999999999824 -0.5 1.3267948966764e-006
+        -0.48907409461153 0.5 -0.10395446108714
+        -0.48907409461153 -0.5 -0.10395446108714
+        -0.45677334042948 0.5 -0.20336694783787
+        -0.45677334042948 -0.5 -0.20336694783787
+        -0.40450943302999 0.5 -0.2938913380652
+        -0.40450943302999 -0.5 -0.2938913380652
+        -0.33456655211184 0.5 -0.3715712881911
+        -0.33456655211184 -0.5 -0.3715712881911
+        -0.25000153204922 0.5 -0.43301181735958
+        -0.25000153204922 -0.5 -0.43301181735958
+        -0.15451026378611 0.5 -0.47552768414126
+        -0.15451026378611 -0.5 -0.47552768414126
+        -0.052266166939075 0.5 -0.49726074427155
+        -0.052266166939075 -0.5 -0.49726074427155
+        0.052262208359312 0.5 -0.4972611603347
+        0.052262208359312 -0.5 -0.4972611603347
+        0.15450647821499 0.5 -0.47552891414676
+        0.15450647821499 -0.5 -0.47552891414676
+        0.24999808493408 0.5 -0.4330138075504
+        0.24999808493408 -0.5 -0.4330138075504
+        0.3345635941079 0.5 -0.37157395158649
+        0.3345635941079 -0.5 -0.37157395158649
+        0.40450709341601 0.5 -0.2938945582622
+        0.40450709341601 -0.5 -0.2938945582622
+        0.45677172145764 0.5 -0.20337058409865
+        0.45677172145764 -0.5 -0.20337058409865
+        0.48907326703854 0.5 -0.10395835448992
+        0.48907326703854 -0.5 -0.10395835448992
+        0 -0.5 0
+        0.5 0.5 0
+        0.5 -0.5 0
+        0.48907381875731 0.5 0.1039557588888
+        0.48907381875731 -0.5 0.1039557588888
+        0.45677280077542 0.5 0.20336815992623
+        0.45677280077542 -0.5 0.20336815992623
+        0.40450865316151 0.5 0.29389241146627
+        0.40450865316151 -0.5 0.29389241146627
+        0.33456556611288 0.5 0.37157217599218
+        0.33456556611288 -0.5 0.37157217599218
+        0.2500003830126 0.5 0.43301248075957
+        0.2500003830126 -0.5 0.43301248075957
+        0.15450900193016 0.5 0.47552809414644
+        0.15450900193016 -0.5 0.47552809414644
+        0.052264847412855 0.5 0.49726088296277
+        0.052264847412855 -0.5 0.49726088296277
+        -0.052263527886268 0.5 0.49726102165048
+        -0.052263527886268 -0.5 0.49726102165048
+        -0.15450774007312 0.5 0.47552850414828
+        -0.15450774007312 -0.5 0.47552850414828
+        -0.24999923397422 0.5 0.43301314415651
+        -0.24999923397422 -0.5 0.43301314415651
+        -0.33456458011157 0.5 0.37157306379065
+        -0.33456458011157 -0.5 0.37157306379065
+        -0.40450787329018 0.5 0.29389348486527
+        -0.40450787329018 -0.5 0.29389348486527
+        -0.45677226111814 0.5 0.20336937201315
+        -0.45677226111814 -0.5 0.20336937201315
+        -0.48907354289964 0.5 0.10395705668972
+        -0.48907354289964 -0.5 0.10395705668972
+        -0.49999999999824 0.5 1.3267948966764e-006
+        -0.49999999999824 -0.5 1.3267948966764e-006
+        -0.48907409461153 0.5 -0.10395446108714
+        -0.48907409461153 -0.5 -0.10395446108714
+        -0.45677334042948 0.5 -0.20336694783787
+        -0.45677334042948 -0.5 -0.20336694783787
+        -0.40450943302999 0.5 -0.2938913380652
+        -0.40450943302999 -0.5 -0.2938913380652
+        -0.33456655211184 0.5 -0.3715712881911
+        -0.33456655211184 -0.5 -0.3715712881911
+        -0.25000153204922 0.5 -0.43301181735958
+        -0.25000153204922 -0.5 -0.43301181735958
+        -0.15451026378611 0.5 -0.47552768414126
+        -0.15451026378611 -0.5 -0.47552768414126
+        -0.052266166939075 0.5 -0.49726074427155
+        -0.052266166939075 -0.5 -0.49726074427155
+        0.052262208359312 0.5 -0.4972611603347
+        0.052262208359312 -0.5 -0.4972611603347
+        0.15450647821499 0.5 -0.47552891414676
+        0.15450647821499 -0.5 -0.47552891414676
+        0.24999808493408 0.5 -0.4330138075504
+        0.24999808493408 -0.5 -0.4330138075504
+        0.3345635941079 0.5 -0.37157395158649
+        0.3345635941079 -0.5 -0.37157395158649
+        0.40450709341601 0.5 -0.2938945582622
+        0.40450709341601 -0.5 -0.2938945582622
+        0.45677172145764 0.5 -0.20337058409865
+        0.45677172145764 -0.5 -0.20337058409865
+        0.48907326703854 0.5 -0.10395835448992
+        0.48907326703854 -0.5 -0.10395835448992</attribute>
+	<attribute index="1" type="float" size="4" > 
+        1 1 1 1
+        0.9 0.5 0.5 1
+        0.9 0.5 0.5 1
+        0.82 0.42 0.42 1
+        0.82 0.42 0.42 1
+        0.74 0.34 0.34 1
+        0.74 0.34 0.34 1
+        0.66 0.26 0.26 1
+        0.66 0.26 0.26 1
+        0.58 0.18 0.18 1
+        0.58 0.18 0.18 1
+        0.5 0.1 0.1 1
+        0.5 0.1 0.1 1
+        0.58 0.18 0.18 1
+        0.58 0.18 0.18 1
+        0.66 0.26 0.26 1
+        0.66 0.26 0.26 1
+        0.74 0.34 0.34 1
+        0.74 0.34 0.34 1
+        0.82 0.42 0.42 1
+        0.82 0.42 0.42 1
+        0.9 0.5 0.5 1
+        0.9 0.5 0.5 1
+        0.82 0.42 0.42 1
+        0.82 0.42 0.42 1
+        0.74 0.34 0.34 1
+        0.74 0.34 0.34 1
+        0.66 0.26 0.26 1
+        0.66 0.26 0.26 1
+        0.58 0.18 0.18 1
+        0.58 0.18 0.18 1
+        0.5 0.1 0.1 1
+        0.5 0.1 0.1 1
+        0.58 0.18 0.18 1
+        0.58 0.18 0.18 1
+        0.66 0.26 0.26 1
+        0.66 0.26 0.26 1
+        0.74 0.34 0.34 1
+        0.74 0.34 0.34 1
+        0.82 0.42 0.42 1
+        0.82 0.42 0.42 1
+        0.9 0.5 0.5 1
+        0.9 0.5 0.5 1
+        0.82 0.42 0.42 1
+        0.82 0.42 0.42 1
+        0.74 0.34 0.34 1
+        0.74 0.34 0.34 1
+        0.66 0.26 0.26 1
+        0.66 0.26 0.26 1
+        0.58 0.18 0.18 1
+        0.58 0.18 0.18 1
+        0.5 0.1 0.1 1
+        0.5 0.1 0.1 1
+        0.58 0.18 0.18 1
+        0.58 0.18 0.18 1
+        0.66 0.26 0.26 1
+        0.66 0.26 0.26 1
+        0.74 0.34 0.34 1
+        0.74 0.34 0.34 1
+        0.82 0.42 0.42 1
+        0.82 0.42 0.42 1
+        1 1 1 1
+        0.9 0.5 0.5 1
+        0.9 0.5 0.5 1
+        0.82 0.42 0.42 1
+        0.82 0.42 0.42 1
+        0.74 0.34 0.34 1
+        0.74 0.34 0.34 1
+        0.66 0.26 0.26 1
+        0.66 0.26 0.26 1
+        0.58 0.18 0.18 1
+        0.58 0.18 0.18 1
+        0.5 0.1 0.1 1
+        0.5 0.1 0.1 1
+        0.58 0.18 0.18 1
+        0.58 0.18 0.18 1
+        0.66 0.26 0.26 1
+        0.66 0.26 0.26 1
+        0.74 0.34 0.34 1
+        0.74 0.34 0.34 1
+        0.82 0.42 0.42 1
+        0.82 0.42 0.42 1
+        0.9 0.5 0.5 1
+        0.9 0.5 0.5 1
+        0.82 0.42 0.42 1
+        0.82 0.42 0.42 1
+        0.74 0.34 0.34 1
+        0.74 0.34 0.34 1
+        0.66 0.26 0.26 1
+        0.66 0.26 0.26 1
+        0.58 0.18 0.18 1
+        0.58 0.18 0.18 1
+        0.5 0.1 0.1 1
+        0.5 0.1 0.1 1
+        0.58 0.18 0.18 1
+        0.58 0.18 0.18 1
+        0.66 0.26 0.26 1
+        0.66 0.26 0.26 1
+        0.74 0.34 0.34 1
+        0.74 0.34 0.34 1
+        0.82 0.42 0.42 1
+        0.82 0.42 0.42 1
+        0.9 0.5 0.5 1
+        0.9 0.5 0.5 1
+        0.82 0.42 0.42 1
+        0.82 0.42 0.42 1
+        0.74 0.34 0.34 1
+        0.74 0.34 0.34 1
+        0.66 0.26 0.26 1
+        0.66 0.26 0.26 1
+        0.58 0.18 0.18 1
+        0.58 0.18 0.18 1
+        0.5 0.1 0.1 1
+        0.5 0.1 0.1 1
+        0.58 0.18 0.18 1
+        0.58 0.18 0.18 1
+        0.66 0.26 0.26 1
+        0.66 0.26 0.26 1
+        0.74 0.34 0.34 1
+        0.74 0.34 0.34 1
+        0.82 0.42 0.42 1
+        0.82 0.42 0.42 1</attribute>
+	<attribute index="2" type="float" size="3" > 
+        0 1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 1 0
+        0 -1 0
+        0 -1 0
+        1 0 0
+        1 0 0
+        0.97814763751461 0 0.20791151777759
+        0.97814763751461 0 0.20791151777759
+        0.91354560155084 0 0.40673631985245
+        0.91354560155084 0 0.40673631985245
+        0.80901730632302 0 0.58778482293254
+        0.80901730632302 0 0.58778482293254
+        0.66913113222576 0 0.74314435198437
+        0.66913113222576 0 0.74314435198437
+        0.5000007660252 0 0.86602496151913
+        0.5000007660252 0 0.86602496151913
+        0.30901800386032 0 0.95105618829288
+        0.30901800386032 0 0.95105618829288
+        0.10452969482571 0 0.99452176592553
+        0.10452969482571 0 0.99452176592553
+        -0.10452705577254 0 0.99452204330096
+        -0.10452705577254 0 0.99452204330096
+        -0.30901548014624 0 0.95105700829655
+        -0.30901548014624 0 0.95105700829655
+        -0.49999846794844 0 0.86602628831301
+        -0.49999846794844 0 0.86602628831301
+        -0.66912916022314 0 0.7431461275813
+        -0.66912916022314 0 0.7431461275813
+        -0.80901574658037 0 0.58778696973054
+        -0.80901574658037 0 0.58778696973054
+        -0.91354452223627 0 0.40673874402631
+        -0.91354452223627 0 0.40673874402631
+        -0.97814708579929 0 0.20791411337945
+        -0.97814708579929 0 0.20791411337945
+        -0.99999999999648 0 2.6535897933527e-006
+        -0.99999999999648 0 2.6535897933527e-006
+        -0.97814818922305 0 -0.20790892217427
+        -0.97814818922305 0 -0.20790892217427
+        -0.91354668085897 0 -0.40673389567574
+        -0.91354668085897 0 -0.40673389567574
+        -0.80901886605998 0 -0.58778267613041
+        -0.80901886605998 0 -0.58778267613041
+        -0.66913310422368 0 -0.74314257638221
+        -0.66913310422368 0 -0.74314257638221
+        -0.50000306409843 0 -0.86602363471916
+        -0.50000306409843 0 -0.86602363471916
+        -0.30902052757222 0 -0.95105536828251
+        -0.30902052757222 0 -0.95105536828251
+        -0.10453233387815 0 -0.9945214885431
+        -0.10453233387815 0 -0.9945214885431
+        0.10452441671862 0 -0.99452232066939
+        0.10452441671862 0 -0.99452232066939
+        0.30901295642998 0 -0.95105782829353
+        0.30901295642998 0 -0.95105782829353
+        0.49999616986816 0 -0.8660276151008
+        0.49999616986816 0 -0.8660276151008
+        0.66912718821581 0 -0.74314790317299
+        0.66912718821581 0 -0.74314790317299
+        0.80901418683202 0 -0.5877891165244
+        0.80901418683202 0 -0.5877891165244
+        0.91354344291528 0 -0.40674116819729
+        0.91354344291528 0 -0.40674116819729
+        0.97814653407707 0 -0.20791670897984
+        0.97814653407707 0 -0.20791670897984</attribute>
+	<vao name="lit-color" >
+		<source attrib="0" />
+		<source attrib="1" />
+		<source attrib="2" />
+	</vao>
+	<vao name="lit" >
+		<source attrib="0" />
+		<source attrib="2" />
+	</vao>
+	<vao name="color" >
+		<source attrib="0" />
+		<source attrib="1" />
+	</vao>
+	<indices cmd="tri-fan" type="ushort" >0 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 1</indices>
+	<indices cmd="tri-fan" type="ushort" >61 60 58 56 54 52 50 48 46 44 42 40 38 36 34 32 30 28 26 24 22 20 18 16 14 12 10 8 6 4 2 60</indices>
+	<indices cmd="tri-strip" type="ushort" >62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 62 63</indices>
+</mesh>

File Tut 12 Dynamic Range/data/UnitSphere.xml

 <mesh xmlns="http://www.arcsynthesis.com/gltut/mesh" >
 	<attribute index="0" type="float" size="3" > 
         0 0.5 0
-        0.25 0.43301270189222 0
-        0.20225424859374 0.43301270189222 0.14694631307312
-        0.077254248593737 0.43301270189222 0.23776412907379
-        -0.077254248593737 0.43301270189222 0.23776412907379
-        -0.20225424859374 0.43301270189222 0.14694631307312
-        -0.25 0.43301270189222 3.0615158845559e-017
-        -0.20225424859374 0.43301270189222 -0.14694631307312
-        -0.077254248593737 0.43301270189222 -0.23776412907379
-        0.077254248593737 0.43301270189222 -0.23776412907379
-        0.20225424859374 0.43301270189222 -0.14694631307312
+        0.17101007166283 0.46984631039295 0
+        0.15622547417872 0.46984631039295 0.069556062480293
+        0.11442807294522 0.46984631039295 0.12708524986075
+        0.052845018353093 0.46984631039295 0.16264024300704
+        -0.017875419994207 0.46984631039295 0.17007326059719
+        -0.085505035831417 0.46984631039295 0.14809906636301
+        -0.13835005418451 0.46984631039295 0.10051719811689
+        -0.16727309129832 0.46984631039295 0.035554993146286
+        -0.16727309129832 0.46984631039295 -0.035554993146286
+        -0.13835005418451 0.46984631039295 -0.10051719811689
+        -0.085505035831417 0.46984631039295 -0.14809906636301
+        -0.017875419994207 0.46984631039295 -0.17007326059719
+        0.052845018353093 0.46984631039295 -0.16264024300704
+        0.11442807294522 0.46984631039295 -0.12708524986075
+        0.15622547417872 0.46984631039295 -0.069556062480293
+        0.32139380484327 0.38302222155949 0
+        0.29360785052904 0.38302222155949 0.13072263728731
+        0.21505443151476 0.38302222155949 0.23884214300977
+        0.099316147583396 0.38302222155949 0.30566367239308
+        -0.033594800524011 0.38302222155949 0.31963317595235
+        -0.16069690242163 0.38302222155949 0.27833519961321
+        -0.26001305000503 0.38302222155949 0.18891053866504
+        -0.31437057909815 0.38302222155949 0.066821529383317
+        -0.31437057909815 0.38302222155949 -0.066821529383317
+        -0.26001305000503 0.38302222155949 -0.18891053866504
+        -0.16069690242163 0.38302222155949 -0.27833519961321
+        -0.033594800524011 0.38302222155949 -0.31963317595235
+        0.099316147583396 0.38302222155949 -0.30566367239308
+        0.21505443151476 0.38302222155949 -0.23884214300977
+        0.29360785052904 0.38302222155949 -0.13072263728731
         0.43301270189222 0.25 0
-        0.35031463461102 0.25 0.25451848022756
+        0.39557678691519 0.25 0.17612213277682
+        0.28974205177823 0.25 0.32179114877719
         0.13380828366491 0.25 0.41181955177317
-        -0.13380828366491 0.25 0.41181955177317
+        -0.045262152304168 0.25 0.43064061300439
+        -0.21650635094611 0.25 0.375
         -0.35031463461102 0.25 0.25451848022756
-        -0.43301270189222 0.25 5.3027010602301e-017
+        -0.42355033544314 0.25 0.090028402995978
+        -0.42355033544314 0.25 -0.090028402995978
         -0.35031463461102 0.25 -0.25451848022756
-        -0.13380828366491 0.25 -0.41181955177317
+        -0.21650635094611 0.25 -0.375
+        -0.045262152304169 0.25 -0.43064061300439
         0.13380828366491 0.25 -0.41181955177317
-        0.35031463461102 0.25 -0.25451848022756
-        0.5 3.0615158845559e-017 0
-        0.40450849718747 3.0615158845559e-017 0.29389262614624
-        0.15450849718747 3.0615158845559e-017 0.47552825814758
-        -0.15450849718747 3.0615158845559e-017 0.47552825814758
-        -0.40450849718747 3.0615158845559e-017 0.29389262614624
-        -0.5 3.0615158845559e-017 6.1230317691119e-017
-        -0.40450849718747 3.0615158845559e-017 -0.29389262614624
-        -0.15450849718747 3.0615158845559e-017 -0.47552825814758
-        0.15450849718747 3.0615158845559e-017 -0.47552825814758
-        0.40450849718747 3.0615158845559e-017 -0.29389262614624
+        0.28974205177823 0.25 -0.32179114877719
+        0.39557678691519 0.25 -0.17612213277682
+        0.4924038765061 0.086824088833465 0
+        0.44983332470776 0.086824088833465 0.2002786997676
+        0.32948250445998 0.086824088833465 0.36592739287052
+        0.15216116593649 0.086824088833465 0.46830391540012
+        -0.051470220518218 0.086824088833465 0.48970643654954
+        -0.24620193825305 0.086824088833465 0.42643426597622
+        -0.39836310418954 0.086824088833465 0.28942773678193
+        -0.48164367039647 0.086824088833465 0.1023765225296
+        -0.48164367039647 0.086824088833465 -0.1023765225296
+        -0.39836310418954 0.086824088833465 -0.28942773678193
+        -0.24620193825305 0.086824088833465 -0.42643426597622
+        -0.051470220518219 0.086824088833465 -0.48970643654954
+        0.15216116593649 0.086824088833465 -0.46830391540012
+        0.32948250445998 0.086824088833465 -0.36592739287052
+        0.44983332470776 0.086824088833465 -0.2002786997676
+        0.4924038765061 -0.086824088833465 0
+        0.44983332470776 -0.086824088833465 0.2002786997676
+        0.32948250445998 -0.086824088833465 0.36592739287052
+        0.15216116593649 -0.086824088833465 0.46830391540012
+        -0.051470220518218 -0.086824088833465 0.48970643654954
+        -0.24620193825305 -0.086824088833465 0.42643426597622
+        -0.39836310418954 -0.086824088833465 0.28942773678193
+        -0.48164367039647 -0.086824088833465 0.1023765225296
+        -0.48164367039647 -0.086824088833465 -0.1023765225296
+        -0.39836310418954 -0.086824088833465 -0.28942773678193
+        -0.24620193825305 -0.086824088833465 -0.42643426597622
+        -0.051470220518219 -0.086824088833465 -0.48970643654954
+        0.15216116593649 -0.086824088833465 -0.46830391540012
+        0.32948250445998 -0.086824088833465 -0.36592739287052
+        0.44983332470776 -0.086824088833465 -0.2002786997676
         0.43301270189222 -0.25 0
-        0.35031463461102 -0.25 0.25451848022756
+        0.39557678691519 -0.25 0.17612213277682
+        0.28974205177823 -0.25 0.32179114877719
         0.13380828366491 -0.25 0.41181955177317
-        -0.13380828366491 -0.25 0.41181955177317
+        -0.045262152304168 -0.25 0.43064061300439
+        -0.21650635094611 -0.25 0.375
         -0.35031463461102 -0.25 0.25451848022756
-        -0.43301270189222 -0.25 5.3027010602301e-017
+        -0.42355033544314 -0.25 0.090028402995978
+        -0.42355033544314 -0.25 -0.090028402995978
         -0.35031463461102 -0.25 -0.25451848022756
-        -0.13380828366491 -0.25 -0.41181955177317
+        -0.21650635094611 -0.25 -0.375
+        -0.045262152304169 -0.25 -0.43064061300439
         0.13380828366491 -0.25 -0.41181955177317
-        0.35031463461102 -0.25 -0.25451848022756
-        0.25 -0.43301270189222 0
-        0.20225424859374 -0.43301270189222 0.14694631307312
-        0.077254248593737 -0.43301270189222 0.23776412907379
-        -0.077254248593737 -0.43301270189222 0.23776412907379
-        -0.20225424859374 -0.43301270189222 0.14694631307312
-        -0.25 -0.43301270189222 3.0615158845559e-017
-        -0.20225424859374 -0.43301270189222 -0.14694631307312
-        -0.077254248593737 -0.43301270189222 -0.23776412907379
-        0.077254248593737 -0.43301270189222 -0.23776412907379
-        0.20225424859374 -0.43301270189222 -0.14694631307312
+        0.28974205177823 -0.25 -0.32179114877719
+        0.39557678691519 -0.25 -0.17612213277682
+        0.32139380484327 -0.38302222155949 0
+        0.29360785052904 -0.38302222155949 0.13072263728731
+        0.21505443151476 -0.38302222155949 0.23884214300977
+        0.099316147583396 -0.38302222155949 0.30566367239308
+        -0.033594800524011 -0.38302222155949 0.31963317595235
+        -0.16069690242163 -0.38302222155949 0.27833519961321
+        -0.26001305000503 -0.38302222155949 0.18891053866504
+        -0.31437057909815 -0.38302222155949 0.066821529383317
+        -0.31437057909815 -0.38302222155949 -0.066821529383317
+        -0.26001305000503 -0.38302222155949 -0.18891053866504
+        -0.16069690242164 -0.38302222155949 -0.27833519961321
+        -0.033594800524011 -0.38302222155949 -0.31963317595235
+        0.099316147583396 -0.38302222155949 -0.30566367239308
+        0.21505443151476 -0.38302222155949 -0.23884214300977
+        0.29360785052904 -0.38302222155949 -0.13072263728731
+        0.17101007166283 -0.46984631039295 0
+        0.15622547417872 -0.46984631039295 0.069556062480293
+        0.11442807294522 -0.46984631039295 0.12708524986075
+        0.052845018353093 -0.46984631039295 0.16264024300704
+        -0.017875419994207 -0.46984631039295 0.17007326059719
+        -0.085505035831417 -0.46984631039295 0.14809906636301
+        -0.13835005418451 -0.46984631039295 0.10051719811689
+        -0.16727309129832 -0.46984631039295 0.035554993146286
+        -0.16727309129832 -0.46984631039295 -0.035554993146286
+        -0.13835005418451 -0.46984631039295 -0.10051719811689
+        -0.085505035831417 -0.46984631039295 -0.14809906636301
+        -0.017875419994208 -0.46984631039295 -0.17007326059719
+        0.052845018353093 -0.46984631039295 -0.16264024300704
+        0.11442807294522 -0.46984631039295 -0.12708524986075
+        0.15622547417872 -0.46984631039295 -0.069556062480293
         0 -0.5 0</attribute>
 	<attribute index="1" type="float" size="4" > 
         1 1 1 1
-        0.5 0.86602540378444 0 1
-        0.40450849718747 0.86602540378444 0.29389262614624 1
-        0.15450849718747 0.86602540378444 0.47552825814758 1
-        -0.15450849718747 0.86602540378444 0.47552825814758 1
-        -0.40450849718747 0.86602540378444 0.29389262614624 1
-        -0.5 0.86602540378444 6.1230317691119e-017 1
-        -0.40450849718747 0.86602540378444 -0.29389262614624 1
-        -0.15450849718747 0.86602540378444 -0.47552825814758 1
-        0.15450849718747 0.86602540378444 -0.47552825814758 1
-        0.40450849718747 0.86602540378444 -0.29389262614624 1
+        0.34202014332567 0.93969262078591 0 1
+        0.31245094835744 0.93969262078591 0.13911212496059 1
+        0.22885614589045 0.93969262078591 0.25417049972151 1
+        0.10569003670619 0.93969262078591 0.32528048601408 1
+        -0.035750839988415 0.93969262078591 0.34014652119437 1
+        -0.17101007166283 0.93969262078591 0.29619813272602 1
+        -0.27670010836902 0.93969262078591 0.20103439623379 1
+        -0.33454618259664 0.93969262078591 0.071109986292572 1
+        -0.33454618259664 0.93969262078591 -0.071109986292572 1
+        -0.27670010836902 0.93969262078591 -0.20103439623379 1
+        -0.17101007166283 0.93969262078591 -0.29619813272602 1
+        -0.035750839988415 0.93969262078591 -0.34014652119437 1
+        0.10569003670619 0.93969262078591 -0.32528048601408 1
+        0.22885614589045 0.93969262078591 -0.25417049972151 1
+        0.31245094835744 0.93969262078591 -0.13911212496059 1
+        0.64278760968654 0.76604444311898 0 1
+        0.58721570105808 0.76604444311898 0.26144527457462 1
+        0.43010886302952 0.76604444311898 0.47768428601953 1
+        0.19863229516679 0.76604444311898 0.61132734478617 1
+        -0.067189601048022 0.76604444311898 0.6392663519047 1
+        -0.32139380484327 0.76604444311898 0.55667039922642 1
+        -0.52002610001006 0.76604444311898 0.37782107733008 1
+        -0.62874115819631 0.76604444311898 0.13364305876663 1
+        -0.62874115819631 0.76604444311898 -0.13364305876663 1
+        -0.52002610001006 0.76604444311898 -0.37782107733008 1
+        -0.32139380484327 0.76604444311898 -0.55667039922642 1
+        -0.067189601048023 0.76604444311898 -0.6392663519047 1
+        0.19863229516679 0.76604444311898 -0.61132734478617 1
+        0.43010886302951 0.76604444311898 -0.47768428601953 1
+        0.58721570105808 0.76604444311898 -0.26144527457462 1
         0.86602540378444 0.5 0 1
-        0.70062926922204 0.5 0.50903696045513 1
+        0.79115357383037 0.5 0.35224426555365 1
+        0.57948410355646 0.5 0.64358229755438 1
         0.26761656732982 0.5 0.82363910354633 1
-        -0.26761656732982 0.5 0.82363910354633 1
+        -0.090524304608336 0.5 0.86128122600877 1
+        -0.43301270189222 0.5 0.75 1
         -0.70062926922204 0.5 0.50903696045513 1
-        -0.86602540378444 0.5 1.060540212046e-016 1
+        -0.84710067088627 0.5 0.18005680599196 1
+        -0.84710067088627 0.5 -0.18005680599196 1
         -0.70062926922204 0.5 -0.50903696045513 1
-        -0.26761656732982 0.5 -0.82363910354633 1
+        -0.43301270189222 0.5 -0.75 1
+        -0.090524304608337 0.5 -0.86128122600877 1
         0.26761656732982 0.5 -0.82363910354633 1
-        0.70062926922204 0.5 -0.50903696045513 1
-        1 6.1230317691119e-017 0 1
-        0.80901699437495 6.1230317691119e-017 0.58778525229247 1
-        0.30901699437495 6.1230317691119e-017 0.95105651629515 1
-        -0.30901699437495 6.1230317691119e-017 0.95105651629515 1
-        -0.80901699437495 6.1230317691119e-017 0.58778525229247 1
-        -1 6.1230317691119e-017 1.2246063538224e-016 1
-        -0.80901699437495 6.1230317691119e-017 -0.58778525229247 1
-        -0.30901699437495 6.1230317691119e-017 -0.95105651629515 1
-        0.30901699437495 6.1230317691119e-017 -0.95105651629515 1
-        0.80901699437495 6.1230317691119e-017 -0.58778525229247 1
+        0.57948410355646 0.5 -0.64358229755438 1
+        0.79115357383037 0.5 -0.35224426555365 1
+        0.98480775301221 0.17364817766693 0 1
+        0.89966664941552 0.17364817766693 0.40055739953521 1
+        0.65896500891996 0.17364817766693 0.73185478574104 1
+        0.30432233187298 0.17364817766693 0.93660783080025 1
+        -0.10294044103644 0.17364817766693 0.97941287309907 1
+        -0.4924038765061 0.17364817766693 0.85286853195244 1
+        -0.79672620837908 0.17364817766693 0.57885547356386 1
+        -0.96328734079294 0.17364817766693 0.20475304505921 1
+        -0.96328734079294 0.17364817766693 -0.20475304505921 1
+        -0.79672620837908 0.17364817766693 -0.57885547356386 1
+        -0.4924038765061 0.17364817766693 -0.85286853195244 1
+        -0.10294044103644 0.17364817766693 -0.97941287309907 1
+        0.30432233187298 0.17364817766693 -0.93660783080025 1
+        0.65896500891996 0.17364817766693 -0.73185478574104 1
+        0.89966664941552 0.17364817766693 -0.40055739953521 1
+        0.98480775301221 -0.17364817766693 0 1
+        0.89966664941552 -0.17364817766693 0.40055739953521 1
+        0.65896500891996 -0.17364817766693 0.73185478574104 1
+        0.30432233187298 -0.17364817766693 0.93660783080025 1
+        -0.10294044103644 -0.17364817766693 0.97941287309907 1
+        -0.4924038765061 -0.17364817766693 0.85286853195244 1
+        -0.79672620837908 -0.17364817766693 0.57885547356386 1
+        -0.96328734079294 -0.17364817766693 0.20475304505921 1
+        -0.96328734079294 -0.17364817766693 -0.20475304505921 1
+        -0.79672620837908 -0.17364817766693 -0.57885547356386 1
+        -0.4924038765061 -0.17364817766693 -0.85286853195244 1
+        -0.10294044103644 -0.17364817766693 -0.97941287309907 1
+        0.30432233187298 -0.17364817766693 -0.93660783080025 1
+        0.65896500891996 -0.17364817766693 -0.73185478574104 1
+        0.89966664941552 -0.17364817766693 -0.40055739953521 1
         0.86602540378444 -0.5 0 1
-        0.70062926922204 -0.5 0.50903696045513 1
+        0.79115357383037 -0.5 0.35224426555365 1
+        0.57948410355646 -0.5 0.64358229755438 1
         0.26761656732982 -0.5 0.82363910354633 1
-        -0.26761656732982 -0.5 0.82363910354633 1
+        -0.090524304608336 -0.5 0.86128122600877 1
+        -0.43301270189222 -0.5 0.75 1
         -0.70062926922204 -0.5 0.50903696045513 1
-        -0.86602540378444 -0.5 1.060540212046e-016 1
+        -0.84710067088627 -0.5 0.18005680599196 1
+        -0.84710067088627 -0.5 -0.18005680599196 1
         -0.70062926922204 -0.5 -0.50903696045513 1
-        -0.26761656732982 -0.5 -0.82363910354633 1
+        -0.43301270189222 -0.5 -0.75 1
+        -0.090524304608337 -0.5 -0.86128122600877 1
         0.26761656732982 -0.5 -0.82363910354633 1
-        0.70062926922204 -0.5 -0.50903696045513 1
-        0.5 -0.86602540378444 0 1
-        0.40450849718747 -0.86602540378444 0.29389262614624 1
-        0.15450849718747 -0.86602540378444 0.47552825814758 1
-        -0.15450849718747 -0.86602540378444 0.47552825814758 1
-        -0.40450849718747 -0.86602540378444 0.29389262614624 1