Jason McKesson avatar Jason McKesson committed 1fb402b

Tut14: Basic texturing works.

Comments (0)

Files changed (14)

Tut 13 Impostors/data/Unlit.frag

-#version 330
-
-uniform vec4 objectColor;
-
-out vec4 outputColor;
-
-void main()
-{
-	outputColor = objectColor;
-}

Tut 13 Impostors/data/Unlit.vert

-#version 330
-
-layout(std140) uniform;
-
-layout(location = 0) in vec3 position;
-
-uniform Projection
-{
-	mat4 cameraToClipMatrix;
-};
-
-uniform mat4 modelToCameraMatrix;
-
-void main()
-{
-	gl_Position = cameraToClipMatrix * (modelToCameraMatrix * vec4(position, 1.0));
-}

Tut 14 Textures Are Not Pictures/Basic 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("UnitSphere.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.5f);
+
+			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()));
+
+			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;}

Tut 14 Textures Are Not Pictures/data/GenCube.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 =
+{
+	--Front
+	vmath.vec3( 0.5,  0.5,  0.5),
+	vmath.vec3( 0.5, -0.5,  0.5),
+	vmath.vec3(-0.5, -0.5,  0.5),
+	vmath.vec3(-0.5,  0.5,  0.5),
+
+	--Top
+	vmath.vec3( 0.5,  0.5,  0.5),
+	vmath.vec3(-0.5,  0.5,  0.5),
+	vmath.vec3(-0.5,  0.5, -0.5),
+	vmath.vec3( 0.5,  0.5, -0.5),
+
+	--Left
+	vmath.vec3( 0.5,  0.5,  0.5),
+	vmath.vec3( 0.5,  0.5, -0.5),
+	vmath.vec3( 0.5, -0.5, -0.5),
+	vmath.vec3( 0.5, -0.5,  0.5),
+
+	--Back
+	vmath.vec3( 0.5,  0.5, -0.5),
+	vmath.vec3(-0.5,  0.5, -0.5),
+	vmath.vec3(-0.5, -0.5, -0.5),
+	vmath.vec3( 0.5, -0.5, -0.5),
+
+	--Bottom
+	vmath.vec3( 0.5, -0.5,  0.5),
+	vmath.vec3( 0.5, -0.5, -0.5),
+	vmath.vec3(-0.5, -0.5, -0.5),
+	vmath.vec3(-0.5, -0.5,  0.5),
+
+	--Right
+	vmath.vec3(-0.5,  0.5,  0.5),
+	vmath.vec3(-0.5, -0.5,  0.5),
+	vmath.vec3(-0.5, -0.5, -0.5),
+	vmath.vec3(-0.5,  0.5, -0.5),
+};
+
+local normals =
+{
+	--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),
+
+	--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),
+
+	--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),
+
+	--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),
+
+	--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),
+
+	--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 =
+{
+	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.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(0.5, 0.5, 1.0, 1.0),
+
+	vmath.vec4(1.0, 0.5, 0.5, 1.0),
+	vmath.vec4(1.0, 0.5, 0.5, 1.0),
+	vmath.vec4(1.0, 0.5, 0.5, 1.0),
+	vmath.vec4(1.0, 0.5, 0.5, 1.0),
+
+	vmath.vec4(1.0, 1.0, 0.5, 1.0),
+	vmath.vec4(1.0, 1.0, 0.5, 1.0),
+	vmath.vec4(1.0, 1.0, 0.5, 1.0),
+	vmath.vec4(1.0, 1.0, 0.5, 1.0),
+
+	vmath.vec4(0.5, 1.0, 1.0, 1.0),
+	vmath.vec4(0.5, 1.0, 1.0, 1.0),
+	vmath.vec4(0.5, 1.0, 1.0, 1.0),
+	vmath.vec4(0.5, 1.0, 1.0, 1.0),
+
+	vmath.vec4(1.0, 0.5, 1.0, 1.0),
+	vmath.vec4(1.0, 0.5, 1.0, 1.0),
+	vmath.vec4(1.0, 0.5, 1.0, 1.0),
+	vmath.vec4(1.0, 0.5, 1.0, 1.0),
+}
+
+local indices =
+{
+	vmath.vec3(0, 1, 2),
+	vmath.vec3(2, 3, 0),
+
+	vmath.vec3(4, 5, 6),
+	vmath.vec3(6, 7, 4),
+
+	vmath.vec3(8, 9, 10),
+	vmath.vec3(10, 11, 8),
+
+	vmath.vec3(12, 13, 14),
+	vmath.vec3(14, 15, 12),
+
+	vmath.vec3(16, 17, 18),
+	vmath.vec3(18, 19, 16),
+
+	vmath.vec3(20, 21, 22),
+	vmath.vec3(22, 23, 20),
+};
+
+do
+	local writer = XmlWriter.XmlWriter("UnitCube.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("indices");
+			writer:AddAttribute("cmd", "triangles");
+			writer:AddAttribute("type", "ushort");
+			writer:AddText(GenStringFromArray(indices, true));
+		writer:PopElement();
+	writer:PopElement();
+	writer:Close();
+end

Tut 14 Textures Are Not Pictures/data/PN.vert

+#version 330
+
+layout(std140) uniform;
+
+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);
+}

Tut 14 Textures Are Not Pictures/data/ShaderGaussian.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;
+
+
+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);
+	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],
+			cameraSpacePosition, vertexNormal);
+	}
+	
+	outputColor = sqrt(accumLighting); //2.0 gamma correction
+}

Tut 14 Textures Are Not Pictures/data/TextureGaussian.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;
+
+/*	
+	float angleNormalHalf = acos();
+	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],
+			cameraSpacePosition, vertexNormal);
+	}
+	
+	outputColor = sqrt(accumLighting); //2.0 gamma correction
+}

Tut 14 Textures Are Not Pictures/data/UnitCube.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.5 0.5 0.5
+        0.5 -0.5 0.5
+        -0.5 -0.5 0.5
+        -0.5 0.5 0.5
+        0.5 0.5 0.5
+        -0.5 0.5 0.5
+        -0.5 0.5 -0.5
+        0.5 0.5 -0.5
+        0.5 0.5 0.5
+        0.5 0.5 -0.5
+        0.5 -0.5 -0.5
+        0.5 -0.5 0.5
+        0.5 0.5 -0.5
+        -0.5 0.5 -0.5
+        -0.5 -0.5 -0.5
+        0.5 -0.5 -0.5
+        0.5 -0.5 0.5
+        0.5 -0.5 -0.5
+        -0.5 -0.5 -0.5
+        -0.5 -0.5 0.5
+        -0.5 0.5 0.5
+        -0.5 -0.5 0.5
+        -0.5 -0.5 -0.5
+        -0.5 0.5 -0.5</attribute>
+	<attribute index="1" type="float" size="4" > 
+        0.25 1 0.25 1
+        0.25 1 0.25 1
+        0.25 1 0.25 1
+        0.25 1 0.25 1
+        0.5 0.5 1 1
+        0.5 0.5 1 1
+        0.5 0.5 1 1
+        0.5 0.5 1 1
+        1 0.5 0.5 1
+        1 0.5 0.5 1
+        1 0.5 0.5 1
+        1 0.5 0.5 1
+        1 1 0.5 1
+        1 1 0.5 1
+        1 1 0.5 1
+        1 1 0.5 1
+        0.5 1 1 1
+        0.5 1 1 1
+        0.5 1 1 1
+        0.5 1 1 1
+        1 0.5 1 1
+        1 0.5 1 1
+        1 0.5 1 1
+        1 0.5 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" />
+	</vao>
+	<vao name="flat" >
+		<source attrib="0" />
+	</vao>
+	<indices cmd="triangles" type="ushort" > 
+        0 1 2
+        2 3 0
+        4 5 6
+        6 7 4
+        8 9 10
+        10 11 8
+        12 13 14
+        14 15 12
+        16 17 18
+        18 19 16
+        20 21 22
+        22 23 20</indices>
+</mesh>

Tut 14 Textures Are Not Pictures/premake4.lua

+
+dofile("../framework/framework.lua")
+
+SetupSolution("Tutorial14")
+
+dofile("tutorials.lua")

Tut 14 Textures Are Not Pictures/tutorials.lua

+SetupProject("Tut 14 Basic Texture", "Basic Texture.cpp",
+	"data/PN.vert",
+	"data/ShaderGaussian.frag",
+	"data/TextureGaussian.frag")
+
 SetupProject("Tut 14 Perspective Interpolation", "Perspective Interpolation.cpp",
 	"data/SmoothVertexColors.vert",
 	"data/SmoothVertexColors.frag",
+#version 330
+
+uniform vec4 objectColor;
+
+out vec4 outputColor;
+
+void main()
+{
+	outputColor = objectColor;
+}
+#version 330
+
+layout(std140) uniform;
+
+layout(location = 0) in vec3 position;
+
+uniform Projection
+{
+	mat4 cameraToClipMatrix;
+};
+
+uniform mat4 modelToCameraMatrix;
+
+void main()
+{
+	gl_Position = cameraToClipMatrix * (modelToCameraMatrix * vec4(position, 1.0));
+}

framework/directories.h

 #ifdef WIN32
 #define LOCAL_FILE_DIR "data\\"
+#define GLOBAL_FILE_DIR "..\\data\\"
 #endif //WIN32
 
 #ifdef LOAD_X11
 #define LOCAL_FILE_DIR "data/"
+#define GLOBAL_FILE_DIR "../data/"
 #endif //LOAD_X11
 

framework/framework.cpp

 		std::ifstream shaderFile(strFilename.c_str());
 		if(!shaderFile.is_open())
 		{
-			fprintf(stderr, "Cannot load the shader file \"%s\" for the %s shader.\n",
-				strFilename.c_str(), GetShaderName(eShaderType));
-			return 0;
+			strFilename = GLOBAL_FILE_DIR + strShaderFilename;
+			shaderFile.open(strFilename.c_str());
+			if(!shaderFile.is_open())
+			{
+				fprintf(stderr, "Cannot load the shader file \"%s\" for the %s shader.\n",
+					strShaderFilename.c_str(), GetShaderName(eShaderType));
+				return 0;
+			}
 		}
 		std::stringstream shaderData;
 		shaderData << shaderFile.rdbuf();
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.