Commits

Jason McKesson  committed 05113d8

Tut14: Uses 1D texture instead of 2D.

  • Participants
  • Parent commits 9e1bb26

Comments (0)

Files changed (6)

File Tut 14 Textures Are Not Pictures/Basic Texture.cpp

 GLuint g_imposterVAO;
 GLuint g_imposterVBO;
 
+float g_specularShininess = 0.2f;
+
 GLuint CreateGaussianTexture(int cosAngleResolution, int shininessResolution)
 {
 	std::vector<unsigned char> textureData(shininessResolution * cosAngleResolution);
 
 	std::vector<unsigned char>::iterator currIt = textureData.begin();
-	for(int iShin = 0; iShin < shininessResolution; iShin++)
+	for(int iCosAng = 0; iCosAng < cosAngleResolution; iCosAng++)
 	{
-		float shininess = iShin / (float)(shininessResolution - 1);
-		for(int iCosAng = 0; iCosAng < cosAngleResolution; iCosAng++)
-		{
-			float cosAng = iCosAng / (float)(cosAngleResolution - 1);
-			float angle = acosf(cosAng);
-			float exponent = angle / shininess;
-			exponent = -(exponent * exponent);
-			float gaussianTerm = glm::exp(exponent);
+		float cosAng = iCosAng / (float)(cosAngleResolution - 1);
+		float angle = acosf(cosAng);
+		float exponent = angle / g_specularShininess;
+		exponent = -(exponent * exponent);
+		float gaussianTerm = glm::exp(exponent);
 
-			*currIt = (unsigned char)(gaussianTerm * 255.0f);
-			++currIt;
-		}
+		*currIt = (unsigned char)(gaussianTerm * 255.0f);
+		++currIt;
 	}
 
 	GLuint gaussTexture;
 	glGenTextures(1, &gaussTexture);
-	glBindTexture(GL_TEXTURE_2D, gaussTexture);
-	glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, cosAngleResolution, shininessResolution, 0,
+	glBindTexture(GL_TEXTURE_1D, gaussTexture);
+	glTexImage1D(GL_TEXTURE_1D, 0, GL_R8, cosAngleResolution, 0,
 		GL_RED, GL_UNSIGNED_BYTE, &textureData[0]);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
-	glBindTexture(GL_TEXTURE_2D, 0);
+	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_BASE_LEVEL, 0);
+	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAX_LEVEL, 0);
+	glBindTexture(GL_TEXTURE_1D, 0);
 
 	return gaussTexture;
 }
 	MaterialBlock mtl;
 	mtl.diffuseColor = glm::vec4(1.0f, 0.673f, 0.043f, 1.0f);
 	mtl.specularColor = glm::vec4(1.0f, 0.673f, 0.043f, 1.0f) * 0.4f;
-	mtl.specularShininess = 0.2f;
+	mtl.specularShininess = g_specularShininess;
 
 	glGenBuffers(1, &g_materialUniformBuffer);
 	glBindBuffer(GL_UNIFORM_BUFFER, g_materialUniformBuffer);
 				glm::value_ptr(normMatrix));
 
 			glActiveTexture(GL_TEXTURE0 + g_gaussTexUnit);
-			glBindTexture(GL_TEXTURE_2D, g_gaussTextures[g_currTexture]);
+			glBindTexture(GL_TEXTURE_1D, g_gaussTextures[g_currTexture]);
 			glBindSampler(g_gaussTexUnit, g_gaussSampler);
 
 			g_pObjectMesh->Render("lit");
 
 			glBindSampler(g_gaussTexUnit, 0);
-			glBindTexture(GL_TEXTURE_2D, 0);
+			glBindTexture(GL_TEXTURE_1D, 0);
 
 			glUseProgram(0);
 			glBindBufferBase(GL_UNIFORM_BUFFER, g_materialBlockIndex, 0);

File Tut 14 Textures Are Not Pictures/Material Texture.cpp

+#include <string>
+#include <vector>
+#include <stack>
+#include <math.h>
+#include <stdio.h>
+#include <glload/gl_3_3.h>
+#include <GL/freeglut.h>
+#include "../framework/framework.h"
+#include "../framework/Mesh.h"
+#include "../framework/MatrixStack.h"
+#include "../framework/MousePole.h"
+#include "../framework/ObjectPole.h"
+#include "../framework/Timer.h"
+#include "../framework/UniformBlockArray.h"
+#include <glm/glm.hpp>
+#include <glm/gtc/type_ptr.hpp>
+
+#define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
+
+struct ProgramData
+{
+	GLuint theProgram;
+
+	GLuint modelToCameraMatrixUnif;
+	GLuint normalModelToCameraMatrixUnif;
+};
+
+struct UnlitProgData
+{
+	GLuint theProgram;
+
+	GLuint objectColorUnif;
+	GLuint modelToCameraMatrixUnif;
+};
+
+float g_fzNear = 1.0f;
+float g_fzFar = 1000.0f;
+
+ProgramData g_litShaderProg;
+ProgramData g_litTextureProg;
+
+UnlitProgData g_Unlit;
+
+const int g_materialBlockIndex = 0;
+const int g_lightBlockIndex = 1;
+const int g_projectionBlockIndex = 2;
+
+const int g_gaussTexUnit = 0;
+
+UnlitProgData LoadUnlitProgram(const std::string &strVertexShader, const std::string &strFragmentShader)
+{
+	std::vector<GLuint> shaderList;
+
+	shaderList.push_back(Framework::LoadShader(GL_VERTEX_SHADER, strVertexShader));
+	shaderList.push_back(Framework::LoadShader(GL_FRAGMENT_SHADER, strFragmentShader));
+
+	UnlitProgData data;
+	data.theProgram = Framework::CreateProgram(shaderList);
+	data.modelToCameraMatrixUnif = glGetUniformLocation(data.theProgram, "modelToCameraMatrix");
+	data.objectColorUnif = glGetUniformLocation(data.theProgram, "objectColor");
+
+	GLuint projectionBlock = glGetUniformBlockIndex(data.theProgram, "Projection");
+	glUniformBlockBinding(data.theProgram, projectionBlock, g_projectionBlockIndex);
+
+	return data;
+}
+
+ProgramData LoadLitMeshProgram(const std::string &strVertexShader, const std::string &strFragmentShader)
+{
+	std::vector<GLuint> shaderList;
+
+	shaderList.push_back(Framework::LoadShader(GL_VERTEX_SHADER, strVertexShader));
+	shaderList.push_back(Framework::LoadShader(GL_FRAGMENT_SHADER, strFragmentShader));
+
+	ProgramData data;
+	data.theProgram = Framework::CreateProgram(shaderList);
+	data.modelToCameraMatrixUnif = glGetUniformLocation(data.theProgram, "modelToCameraMatrix");
+	data.normalModelToCameraMatrixUnif = glGetUniformLocation(data.theProgram, "normalModelToCameraMatrix");
+
+	GLuint materialBlock = glGetUniformBlockIndex(data.theProgram, "Material");
+	GLuint lightBlock = glGetUniformBlockIndex(data.theProgram, "Light");
+	GLuint projectionBlock = glGetUniformBlockIndex(data.theProgram, "Projection");
+
+	glUniformBlockBinding(data.theProgram, materialBlock, g_materialBlockIndex);
+	glUniformBlockBinding(data.theProgram, lightBlock, g_lightBlockIndex);
+	glUniformBlockBinding(data.theProgram, projectionBlock, g_projectionBlockIndex);
+
+	GLuint gaussianTextureUnif = glGetUniformLocation(data.theProgram, "gaussianTexture");
+	glUseProgram(data.theProgram);
+	glUniform1i(gaussianTextureUnif, g_gaussTexUnit);
+	glUseProgram(0);
+
+	return data;
+}
+
+void InitializePrograms()
+{
+	g_litShaderProg = LoadLitMeshProgram("PN.vert", "ShaderGaussian.frag");
+	g_litTextureProg = LoadLitMeshProgram("PN.vert", "TextureGaussian.frag");
+
+	g_Unlit = LoadUnlitProgram("Unlit.vert", "Unlit.frag");
+}
+
+Framework::RadiusDef radiusDef = {10.0f, 3.0f, 70.0f, 3.5f, 1.5f};
+glm::vec3 objectCenter = glm::vec3(0.0f, 0.0f, 0.0f);
+
+Framework::MousePole g_mousePole(objectCenter, radiusDef);
+Framework::ObjectPole g_objectPole(objectCenter, &g_mousePole);
+
+namespace
+{
+	void MouseMotion(int x, int y)
+	{
+		g_mousePole.GLUTMouseMove(glm::ivec2(x, y));
+		g_objectPole.GLUTMouseMove(glm::ivec2(x, y));
+		glutPostRedisplay();
+	}
+
+	void MouseButton(int button, int state, int x, int y)
+	{
+		g_mousePole.GLUTMouseButton(button, state, glm::ivec2(x, y));
+		g_objectPole.GLUTMouseButton(button, state, glm::ivec2(x, y));
+		glutPostRedisplay();
+	}
+
+	void MouseWheel(int wheel, int direction, int x, int y)
+	{
+		g_mousePole.GLUTMouseWheel(direction, glm::ivec2(x, y));
+		g_objectPole.GLUTMouseWheel(direction, glm::ivec2(x, y));
+		glutPostRedisplay();
+	}
+}
+
+struct ProjectionBlock
+{
+	glm::mat4 cameraToClipMatrix;
+};
+
+struct PerLight
+{
+	glm::vec4 cameraSpaceLightPos;
+	glm::vec4 lightIntensity;
+};
+
+const int NUMBER_OF_LIGHTS = 2;
+
+struct LightBlock
+{
+	glm::vec4 ambientIntensity;
+	float lightAttenuation;
+	float padding[3];
+	PerLight lights[NUMBER_OF_LIGHTS];
+};
+
+struct MaterialBlock
+{
+	glm::vec4 diffuseColor;
+	glm::vec4 specularColor;
+	float specularShininess;
+	float padding[3];
+};
+
+Framework::Mesh *g_pObjectMesh = NULL;
+Framework::Mesh *g_pCubeMesh = NULL;
+
+GLuint g_lightUniformBuffer = 0;
+GLuint g_projectionUniformBuffer = 0;
+GLuint g_materialUniformBuffer = 0;
+
+const int NUM_GAUSS_TEXTURES = 4;
+GLuint g_gaussTextures[NUM_GAUSS_TEXTURES];
+
+GLuint g_gaussSampler = 0;
+
+GLuint g_imposterVAO;
+GLuint g_imposterVBO;
+
+GLuint CreateGaussianTexture(int cosAngleResolution, int shininessResolution)
+{
+	std::vector<unsigned char> textureData(shininessResolution * cosAngleResolution);
+
+	std::vector<unsigned char>::iterator currIt = textureData.begin();
+	for(int iShin = 0; iShin < shininessResolution; iShin++)
+	{
+		float shininess = iShin / (float)(shininessResolution - 1);
+		for(int iCosAng = 0; iCosAng < cosAngleResolution; iCosAng++)
+		{
+			float cosAng = iCosAng / (float)(cosAngleResolution - 1);
+			float angle = acosf(cosAng);
+			float exponent = angle / shininess;
+			exponent = -(exponent * exponent);
+			float gaussianTerm = glm::exp(exponent);
+
+			*currIt = (unsigned char)(gaussianTerm * 255.0f);
+			++currIt;
+		}
+	}
+
+	GLuint gaussTexture;
+	glGenTextures(1, &gaussTexture);
+	glBindTexture(GL_TEXTURE_2D, gaussTexture);
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, cosAngleResolution, shininessResolution, 0,
+		GL_RED, GL_UNSIGNED_BYTE, &textureData[0]);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
+	glBindTexture(GL_TEXTURE_2D, 0);
+
+	return gaussTexture;
+}
+
+int CalcCosAngResolution(int level)
+{
+	const int cosAngleStart = 64;
+	return cosAngleStart * ((int)pow(2.0f, level));
+}
+
+void CreateGaussianTextures()
+{
+	for(int loop = 0; loop < NUM_GAUSS_TEXTURES; loop++)
+	{
+		int cosAngleResolution = CalcCosAngResolution(loop);
+		g_gaussTextures[loop] = CreateGaussianTexture(cosAngleResolution, 32);
+	}
+
+	glGenSamplers(1, &g_gaussSampler);
+	glSamplerParameteri(g_gaussSampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glSamplerParameteri(g_gaussSampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glSamplerParameteri(g_gaussSampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+	glSamplerParameteri(g_gaussSampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+}
+
+
+//Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
+void init()
+{
+	InitializePrograms();
+
+	try
+	{
+		g_pObjectMesh = new Framework::Mesh("Infinity.xml");
+		g_pCubeMesh = new Framework::Mesh("UnitCube.xml");
+	}
+	catch(std::exception &except)
+	{
+		printf(except.what());
+		throw;
+	}
+
+	glutMouseFunc(MouseButton);
+	glutMotionFunc(MouseMotion);
+	glutMouseWheelFunc(MouseWheel);
+
+	glEnable(GL_CULL_FACE);
+	glCullFace(GL_BACK);
+	glFrontFace(GL_CW);
+
+	const float depthZNear = 0.0f;
+	const float depthZFar = 1.0f;
+
+	glEnable(GL_DEPTH_TEST);
+	glDepthMask(GL_TRUE);
+	glDepthFunc(GL_LEQUAL);
+	glDepthRange(depthZNear, depthZFar);
+	glEnable(GL_DEPTH_CLAMP);
+
+	//Setup our Uniform Buffers
+	MaterialBlock mtl;
+	mtl.diffuseColor = glm::vec4(1.0f, 0.673f, 0.043f, 1.0f);
+	mtl.specularColor = glm::vec4(1.0f, 0.673f, 0.043f, 1.0f) * 0.4f;
+	mtl.specularShininess = 0.2f;
+
+	glGenBuffers(1, &g_materialUniformBuffer);
+	glBindBuffer(GL_UNIFORM_BUFFER, g_materialUniformBuffer);
+	glBufferData(GL_UNIFORM_BUFFER, sizeof(MaterialBlock), &mtl, GL_STATIC_DRAW);
+
+	glGenBuffers(1, &g_lightUniformBuffer);
+	glBindBuffer(GL_UNIFORM_BUFFER, g_lightUniformBuffer);
+	glBufferData(GL_UNIFORM_BUFFER, sizeof(LightBlock), NULL, GL_DYNAMIC_DRAW);
+
+	glGenBuffers(1, &g_projectionUniformBuffer);
+	glBindBuffer(GL_UNIFORM_BUFFER, g_projectionUniformBuffer);
+	glBufferData(GL_UNIFORM_BUFFER, sizeof(ProjectionBlock), NULL, GL_DYNAMIC_DRAW);
+
+	//Bind the static buffers.
+	glBindBufferRange(GL_UNIFORM_BUFFER, g_lightBlockIndex, g_lightUniformBuffer,
+		0, sizeof(LightBlock));
+
+	glBindBufferRange(GL_UNIFORM_BUFFER, g_projectionBlockIndex, g_projectionUniformBuffer,
+		0, sizeof(ProjectionBlock));
+
+	glBindBufferRange(GL_UNIFORM_BUFFER, g_materialBlockIndex, g_materialUniformBuffer,
+		0, sizeof(MaterialBlock));
+
+	glBindBuffer(GL_UNIFORM_BUFFER, 0);
+
+	CreateGaussianTextures();
+}
+
+bool g_bDrawCameraPos = false;
+bool g_bDrawLights = true;
+bool g_bUseTexture = false;
+int g_currTexture = 0;
+
+Framework::Timer g_lightTimer = Framework::Timer(Framework::Timer::TT_LOOP, 6.0f);
+
+float g_lightHeight = 1.0f;
+float g_lightRadius = 3.0f;
+
+glm::vec4 CalcLightPosition()
+{
+	const float fLoopDuration = 5.0f;
+	const float fScale = 3.14159f * 2.0f;
+
+	float timeThroughLoop = g_lightTimer.GetAlpha();
+
+	glm::vec4 ret(0.0f, g_lightHeight, 0.0f, 1.0f);
+
+	ret.x = cosf(timeThroughLoop * fScale) * g_lightRadius;
+	ret.z = sinf(timeThroughLoop * fScale) * g_lightRadius;
+
+	return ret;
+}
+
+const float g_fHalfLightDistance = 25.0f;
+const float g_fLightAttenuation = 1.0f / (g_fHalfLightDistance * g_fHalfLightDistance);
+
+//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.
+void display()
+{
+	g_lightTimer.Update();
+
+	glClearColor(0.75f, 0.75f, 1.0f, 1.0f);
+	glClearDepth(1.0f);
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+	if(g_pObjectMesh && g_pCubeMesh)
+	{
+		Framework::MatrixStack modelMatrix;
+		modelMatrix.SetMatrix(g_mousePole.CalcMatrix());
+		const glm::mat4 &worldToCamMat = modelMatrix.Top();
+
+		LightBlock lightData;
+
+		lightData.ambientIntensity = glm::vec4(0.2f, 0.2f, 0.2f, 1.0f);
+		lightData.lightAttenuation = g_fLightAttenuation;
+
+		lightData.lights[0].cameraSpaceLightPos = worldToCamMat * glm::vec4(0.707f, 0.707f, 0.0f, 0.0f);
+		lightData.lights[0].lightIntensity = glm::vec4(0.6f, 0.6f, 0.6f, 1.0f);
+
+		lightData.lights[1].cameraSpaceLightPos = worldToCamMat * CalcLightPosition();
+		lightData.lights[1].lightIntensity = glm::vec4(0.4f, 0.4f, 0.4f, 1.0f);
+
+		glBindBuffer(GL_UNIFORM_BUFFER, g_lightUniformBuffer);
+		glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(lightData), &lightData);
+		glBindBuffer(GL_UNIFORM_BUFFER, 0);
+
+		{
+			glBindBufferRange(GL_UNIFORM_BUFFER, g_materialBlockIndex, g_materialUniformBuffer,
+				0, sizeof(MaterialBlock));
+
+			Framework::MatrixStackPusher push(modelMatrix);
+			modelMatrix.ApplyMatrix(g_objectPole.CalcMatrix());
+			modelMatrix.Scale(2.0f); //The unit sphere has a radius 0.5f.
+
+			glm::mat3 normMatrix(modelMatrix.Top());
+			normMatrix = glm::transpose(glm::inverse(normMatrix));
+
+			ProgramData &prog = g_bUseTexture ? g_litTextureProg : g_litShaderProg;
+
+			glUseProgram(prog.theProgram);
+			glUniformMatrix4fv(prog.modelToCameraMatrixUnif, 1, GL_FALSE,
+				glm::value_ptr(modelMatrix.Top()));
+			glUniformMatrix3fv(prog.normalModelToCameraMatrixUnif, 1, GL_FALSE,
+				glm::value_ptr(normMatrix));
+
+			glActiveTexture(GL_TEXTURE0 + g_gaussTexUnit);
+			glBindTexture(GL_TEXTURE_2D, g_gaussTextures[g_currTexture]);
+			glBindSampler(g_gaussTexUnit, g_gaussSampler);
+
+			g_pObjectMesh->Render("lit");
+
+			glBindSampler(g_gaussTexUnit, 0);
+			glBindTexture(GL_TEXTURE_2D, 0);
+
+			glUseProgram(0);
+			glBindBufferBase(GL_UNIFORM_BUFFER, g_materialBlockIndex, 0);
+		}
+
+		if(g_bDrawLights)
+		{
+			Framework::MatrixStackPusher push(modelMatrix);
+
+			modelMatrix.Translate(glm::vec3(CalcLightPosition()));
+			modelMatrix.Scale(0.25f);
+
+			glUseProgram(g_Unlit.theProgram);
+			glUniformMatrix4fv(g_Unlit.modelToCameraMatrixUnif, 1, GL_FALSE,
+				glm::value_ptr(modelMatrix.Top()));
+
+			glm::vec4 lightColor(1.0f);
+			glUniform4fv(g_Unlit.objectColorUnif, 1, glm::value_ptr(lightColor));
+			g_pCubeMesh->Render("flat");
+		}
+
+		if(g_bDrawCameraPos)
+		{
+			Framework::MatrixStackPusher push(modelMatrix);
+
+			modelMatrix.SetIdentity();
+			modelMatrix.Translate(glm::vec3(0.0f, 0.0f, -g_mousePole.GetLookAtDistance()));
+			modelMatrix.Scale(0.25f);
+
+			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");
+		}
+	}
+
+	glutPostRedisplay();
+	glutSwapBuffers();
+}
+
+//Called whenever the window is resized. The new window size is given, in pixels.
+//This is an opportunity to call glViewport or glScissor to keep up with the change in size.
+void reshape (int w, int h)
+{
+	Framework::MatrixStack persMatrix;
+	persMatrix.Perspective(45.0f, (h / (float)w), g_fzNear, g_fzFar);
+
+	ProjectionBlock projData;
+	projData.cameraToClipMatrix = persMatrix.Top();
+
+	glBindBuffer(GL_UNIFORM_BUFFER, g_projectionUniformBuffer);
+	glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(ProjectionBlock), &projData);
+	glBindBuffer(GL_UNIFORM_BUFFER, 0);
+
+	glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+	glutPostRedisplay();
+}
+
+//Called whenever a key on the keyboard was pressed.
+//The key is given by the ''key'' parameter, which is in ASCII.
+//It's often a good idea to have the escape key (ASCII value 27) call glutLeaveMainLoop() to 
+//exit the program.
+void keyboard(unsigned char key, int x, int y)
+{
+	switch (key)
+	{
+	case 27:
+		delete g_pObjectMesh;
+		delete g_pCubeMesh;
+		g_pObjectMesh = NULL;
+		g_pCubeMesh = NULL;
+		glutLeaveMainLoop();
+		break;
+
+	case 'p': g_lightTimer.TogglePause(); break;
+	case '-': g_lightTimer.Rewind(0.5f); break;
+	case '=': g_lightTimer.Fastforward(0.5f); break;
+	case 't': g_bDrawCameraPos = !g_bDrawCameraPos; break;
+	case 'g': g_bDrawLights = !g_bDrawLights; break;
+	case 32:
+		g_bUseTexture = !g_bUseTexture;
+		if(g_bUseTexture)
+			printf("Texture\n");
+		else
+			printf("Shader\n");
+		break;
+	}
+
+	if(('1' <= key) && (key <= '9'))
+	{
+		int number = key - '1';
+		if(number < NUM_GAUSS_TEXTURES)
+		{
+			printf("Angle Resolution: %i\n", CalcCosAngResolution(number));
+			g_currTexture = number;
+		}
+	}
+
+//	g_mousePole.GLUTKeyOffset(key, 5.0f, 1.0f);
+}
+
+unsigned int defaults(unsigned int displayMode, int &width, int &height) {return displayMode;}

File Tut 14 Textures Are Not Pictures/data/FixedShininess.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 = 2;
+
+uniform Light
+{
+	vec4 ambientIntensity;
+	float lightAttenuation;
+	PerLight lights[numberOfLights];
+} Lgt;
+
+uniform sampler2D gaussianTexture;
+
+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 * lightDistanceSqr));
+}
+
+vec4 ComputeLighting(in PerLight lightData, in vec3 cameraSpacePosition,
+	in vec3 cameraSpaceNormal)
+{
+	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(cameraSpaceNormal);
+	float cosAngIncidence = dot(surfaceNormal, lightDir);
+	cosAngIncidence = cosAngIncidence < 0.0001 ? 0.0 : cosAngIncidence;
+	
+	vec3 viewDirection = normalize(-cameraSpacePosition);
+	
+	vec3 halfAngle = normalize(lightDir + viewDirection);
+	vec2 texCoord;
+	texCoord.s = dot(halfAngle, surfaceNormal);
+	texCoord.t = Mtl.specularShininess;
+	float gaussianTerm = texture(gaussianTexture, texCoord).r;
+
+	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],
+			cameraSpacePosition, vertexNormal);
+	}
+	
+	outputColor = sqrt(accumLighting); //2.0 gamma correction
+}

File Tut 14 Textures Are Not Pictures/data/TextureGaussian.frag

 {
 	vec4 diffuseColor;
 	vec4 specularColor;
-	float specularShininess;
+	float specularShininess;	//Not used in this shader
 } Mtl;
 
 struct PerLight
 	PerLight lights[numberOfLights];
 } Lgt;
 
-uniform sampler2D gaussianTexture;
+uniform sampler1D gaussianTexture;
 
 float CalcAttenuation(in vec3 cameraSpacePosition,
 	in vec3 cameraSpaceLightPos,
 	vec3 viewDirection = normalize(-cameraSpacePosition);
 	
 	vec3 halfAngle = normalize(lightDir + viewDirection);
-	vec2 texCoord;
-	texCoord.s = dot(halfAngle, surfaceNormal);
-	texCoord.t = Mtl.specularShininess;
+	float texCoord = dot(halfAngle, surfaceNormal);
 	float gaussianTerm = texture(gaussianTexture, texCoord).r;
 
 	gaussianTerm = cosAngIncidence != 0.0 ? gaussianTerm : 0.0;

File Tut 14 Textures Are Not Pictures/data/TextureShininess.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 = 2;
+
+uniform Light
+{
+	vec4 ambientIntensity;
+	float lightAttenuation;
+	PerLight lights[numberOfLights];
+} Lgt;
+
+uniform sampler2D gaussianTexture;
+uniform sampler2D 
+
+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 * lightDistanceSqr));
+}
+
+vec4 ComputeLighting(in PerLight lightData, in vec3 cameraSpacePosition,
+	in vec3 cameraSpaceNormal)
+{
+	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(cameraSpaceNormal);
+	float cosAngIncidence = dot(surfaceNormal, lightDir);
+	cosAngIncidence = cosAngIncidence < 0.0001 ? 0.0 : cosAngIncidence;
+	
+	vec3 viewDirection = normalize(-cameraSpacePosition);
+	
+	vec3 halfAngle = normalize(lightDir + viewDirection);
+	vec2 texCoord;
+	texCoord.s = dot(halfAngle, surfaceNormal);
+	texCoord.t = Mtl.specularShininess;
+	float gaussianTerm = texture(gaussianTexture, texCoord).r;
+
+	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],
+			cameraSpacePosition, vertexNormal);
+	}
+	
+	outputColor = sqrt(accumLighting); //2.0 gamma correction
+}

File Tut 14 Textures Are Not Pictures/tutorials.lua

 	"data/SmoothVertexColors.frag",
 	"data/NoCorrectVertexColors.vert",
 	"data/NoCorrectVertexColors.frag")
+
+	--[[
+SetupProject("Tut 14 Material Texture", "Material Texture.cpp",
+	"data/PN.vert",
+	"data/PNT.vert",
+	"data/FixedShininess.frag",
+	"data/TextureShininess.frag")
+	]]
+