Commits

Jason McKesson committed 257a68c

Tut18: Basic bump mapping done.

  • Participants
  • Parent commits cbb3d8d

Comments (0)

Files changed (9)

Documents/sceneFormat.rnc

         sc.prog.frag.attribute,
         sc.prog.geom.attribute?,
         sc.prog.model-to-camera.attribute,
-        sc.prog.normal-model-to-camera.attribute?
+        sc.prog.normal-model-to-camera.attribute?,
+        sc.prog.normal-camera-to-model.attribute?
         
     sc.sampler.attlist =
         sc.sampler.name.attribute, sc.sampler.unit.attribute
     sc.prog.normal-model-to-camera.attribute =
         ##The uniform name of a mat3 that represents the normal model-to-camera transform.
         attribute normal-model-to-camera { acc.uniform.type }
+        
+    sc.prog.normal-camera-to-model.attribute =
+        ##The uniform name of a mat3 that represent the normal camera-to-model transform
+        ##(inverse of the model to camera).
+        attribute normal-camera-to-model { acc.uniform.type }
 
     sc.sampler.name.attribute =
         ##The name of a sampler uniform.

Meshes/ColladaConv.exe

Binary file modified.

Tut 18 Bumpy Textures/Bumpy Square.cpp

 	}
 }
 */
+glutil::ObjectData g_objectData =
+{
+	glm::vec3(0.0f, 1.0f, 0.0f),
+	glm::fquat(1.0f, 0.0f, 0.0f, 0.0f),
+};
 
 glutil::ViewPole *g_pViewPole = NULL;
+glutil::ObjectPole *g_pObjPole = NULL;
 
 namespace
 {
 	void MouseMotion(int x, int y)
 	{
 		if(g_pViewPole)
+		{
 			Framework::ForwardMouseMotion(*g_pViewPole, x, y);
+			Framework::ForwardMouseMotion(*g_pObjPole, x, y);
+		}
 	}
 
 	void MouseButton(int button, int state, int x, int y)
 	{
 		if(g_pViewPole)
+		{
 			Framework::ForwardMouseButton(*g_pViewPole, button, state, x, y);
+			Framework::ForwardMouseButton(*g_pObjPole, button, state, x, y);
+		}
 	}
 
 	void MouseWheel(int wheel, int direction, int x, int y)
 	{
 		if(g_pViewPole)
+		{
 			Framework::ForwardMouseWheel(*g_pViewPole, wheel, direction, x, y);
+		}
 	}
 }
 
 GLuint g_unlitProg;
 Framework::Mesh *g_pSphereMesh = NULL;
 
+
+
 void LoadAndSetupScene()
 {
 	std::auto_ptr<Framework::Scene> pScene(new Framework::Scene("bump_square_scene.xml"));
 	if(pViewPole.get() == NULL)
 		throw std::runtime_error("Could not find the main camera in the scene.");
 
+	std::auto_ptr<glutil::ObjectPole> pObjPole(new glutil::ObjectPole(g_objectData, 0.36f,
+		glutil::MB_RIGHT_BTN, pViewPole.get()));
+
 	//No more things that can throw.
 	g_unlitProg = unlit;
 	g_unlitModelToCameraMatrixUnif = glGetUniformLocation(unlit, "modelToCameraMatrix");
 	g_pViewPole = pViewPole.release();
 	pViewPole.reset(pTemp);		//If something was there already, delete it.
 
+	glutil::ObjectPole *pTempObj = g_pObjPole;
+	g_pObjPole = pObjPole.release();
+	pObjPole.reset(pTempObj);		//If something was there already, delete it.
+
 	Framework::Scene *pOldScene = g_pScene;
 	g_pScene = pScene.release();
 	pScene.reset(pOldScene);	//If something was there already, delete it.
 // int g_currSampler = 0;
 
 bool g_bDrawCameraPos = false;
-bool g_bShowOtherLights = true;
+bool g_bDrawLightPos = true;
 
 int g_displayWidth = 500;
 int g_displayHeight = 500;
 
+const glm::vec4 g_lightPosOffset = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
+
 void BuildLights( const glm::mat4 &camMatrix )
 {
 	LightBlock lightData;
 	lightData.lights[0].lightIntensity = glm::vec4(0.2f, 0.2f, 0.2f, 1.0f);
 	lightData.lights[0].cameraSpaceLightPos = camMatrix *
 		glm::normalize(glm::vec4(-0.2f, 0.5f, 0.5f, 0.0f));
+
 	lightData.lights[1].lightIntensity = glm::vec4(5.0f, 5.0f, 5.0f, 1.0f);
-	lightData.lights[1].cameraSpaceLightPos = camMatrix *
-		glm::vec4(5.0f, 6.0f, 0.5f, 1.0f);
+
+	if(g_pObjPole)
+	{
+		lightData.lights[1].cameraSpaceLightPos = camMatrix * g_pObjPole->CalcMatrix() *
+			g_lightPosOffset;
+	}
+	else
+	{
+		lightData.lights[1].cameraSpaceLightPos = camMatrix *
+			glm::vec4(5.0f, 6.0f, 0.5f, 1.0f);
+	}
 
 	g_lightNumBinder.SetValue(2);
 
 
 	g_pScene->Render(modelMatrix.Top());
 
+	if(g_pObjPole && g_bDrawLightPos)
+	{
+		glutil::PushStack stackPush(modelMatrix);
+		modelMatrix.ApplyMatrix(g_pObjPole->CalcMatrix());
+		modelMatrix.Translate(glm::vec3(g_lightPosOffset.x, g_lightPosOffset.y, g_lightPosOffset.z));
+		modelMatrix.Scale(0.0625f);
+
+		glUseProgram(g_unlitProg);
+		glUniformMatrix4fv(g_unlitModelToCameraMatrixUnif, 1, GL_FALSE,
+			glm::value_ptr(modelMatrix.Top()));
+		glUniform4f(g_unlitObjectColorUnif, 0.25f, 0.25f, 0.25f, 1.0f);
+		g_pSphereMesh->Render("flat");
+	}
+
 	if(g_bDrawCameraPos)
 	{
 		//Draw lookat point.
 		g_bDrawCameraPos = !g_bDrawCameraPos;
 		break;
 	case 'g':
-		g_bShowOtherLights = !g_bShowOtherLights;
+		g_bDrawLightPos = !g_bDrawLightPos;
 		break;
 	case 'p':
 		g_timer.TogglePause();
 	}
 
 	if(g_pViewPole)
+	{
 		g_pViewPole->CharPress(key);
+		g_pObjPole->CharPress(key);
+	}
 }
 
 unsigned int defaults(unsigned int displayMode, int &width, int &height)

Tut 18 Bumpy Textures/data/bump_square_scene.xml

     <mesh xml:id="m_sphere" file="UnitSphere.xml"/>
     <mesh xml:id="m_cube" file="UnitCube.xml"/>
     <mesh xml:id="m_plane" file="UnitPlane.xml"/>
-    <mesh xml:id="m_square" file="UnitPlane.xml"/>
+    <mesh xml:id="m_square" file="square_tan.xml"/>
     
     <texture xml:id="t_sandy_ground" file="dsc_1621_small.dds"/>
-    <texture xml:id="t_bump_texture" file="dsc_1621_small.dds"/>
+    <texture xml:id="t_bump_texture" file="square_normal.png"/>
     <prog
         xml:id="p_litBump"
         vert="litBump.vert"
         frag="litBump.frag"
         model-to-camera="modelToCameraMatrix"
-        normal-model-to-camera="normalModelToCameraMatrix">
+        normal-camera-to-model="normalCameraToModelMatrix">
         <block name="Projection" binding="0"/>
         <block name="Light" binding="1"/>
-        <sampler name="normalTex" unit="0"/>
+        <sampler name="normalTex" unit="2"/>
     </prog>
     <prog
         xml:id="p_lit"
     </prog>
     
     <camera xml:id="c_main"
-        start-pos="0.0 1.0 0.0"
+        start-pos="0 1 -1"
         start-orient="0.074608 -0.137399 -0.010379 0.987647"
         start-radius="5.0"
         start-up-spin="0"
         name="object"
         mesh="m_square"
         prog="p_litBump"
-        orient="0.707 0 0 0.707"
+        orient="0 0 0 1"
         pos="0 1 -1"
         scale="1">
-        <texture name="t_bump_texture" unit="0" sampler="anisotropic"/>
+        <texture name="t_bump_texture" unit="2" sampler="linear"/>
     </node>
     
     <node

Tut 18 Bumpy Textures/data/litBump.frag

 #version 330
 
-in vec2 colorCoord;
+in vec2 normalCoord;
 in vec3 cameraSpacePosition;
 in vec3 cameraSpaceNormal;
+in vec3 cameraSpaceTangent;
+in vec3 cameraSpaceBitangent;
 
 out vec4 outputColor;
 
 	return (1 / ( 1.0 + Lgt.lightAttenuation * lightDistanceSqr));
 }
 
-vec4 ComputeLighting(in vec4 diffuseColor, in PerLight lightData)
+vec3 CalcLightDir(in vec3 lightDir)
+{
+	vec3 ret = normalize(cameraSpaceTangent) * lightDir.x;
+	ret += normalize(cameraSpaceBitangent) * lightDir.y;
+	ret += normalize(cameraSpaceNormal) * lightDir.z;
+	return ret;
+}
+
+vec4 ComputeLighting(in vec4 diffuseColor, in vec3 normal, in PerLight lightData)
 {
 	vec3 lightDir;
 	vec4 lightIntensity;
 		lightIntensity = atten * lightData.lightIntensity;
 	}
 	
-	vec3 surfaceNormal = normalize(cameraSpaceNormal);
-	float cosAngIncidence = dot(surfaceNormal, lightDir);
+	lightDir = CalcLightDir(lightDir);
+	
+	float cosAngIncidence = dot(normal, lightDir);
 	cosAngIncidence = cosAngIncidence < 0.0001 ? 0.0 : cosAngIncidence;
 	
 	vec4 lighting = diffuseColor * lightIntensity * cosAngIncidence;
 
 void main()
 {
-	vec4 diffuseColor = texture(normalTex, colorCoord);
+	vec4 diffuseColor = vec4(0.8, 0.8, 1.0, 1.0);
+	
+	vec3 normal = texture(normalTex, normalCoord).xyz;
+	normal = (normal * 2.0) - 1.0;
 
 	vec4 accumLighting = diffuseColor * Lgt.ambientIntensity;
 	for(int light = 0; light < numberOfLights; light++)
 	{
-		accumLighting += ComputeLighting(diffuseColor, Lgt.lights[light]);
+		accumLighting += ComputeLighting(diffuseColor, normal, Lgt.lights[light]);
 	}
 	
 	outputColor = accumLighting / Lgt.maxIntensity;

Tut 18 Bumpy Textures/data/litBump.vert

 
 layout(location = 0) in vec3 position;
 layout(location = 2) in vec3 normal;
+layout(location = 3) in vec3 tangent;
+layout(location = 4) in vec3 bitangent;
 layout(location = 5) in vec2 texCoord;
 
-out vec2 colorCoord;
+out vec2 normalCoord;
 out vec3 cameraSpacePosition;
 out vec3 cameraSpaceNormal;
+out vec3 cameraSpaceTangent;
+out vec3 cameraSpaceBitangent;
 
 uniform Projection
 {
 };
 
 uniform mat4 modelToCameraMatrix;
-uniform mat3 normalModelToCameraMatrix;
+uniform mat3 normalCameraToModelMatrix;
 
 void main()
 {
 	cameraSpacePosition = (modelToCameraMatrix * vec4(position, 1.0)).xyz;
 	gl_Position = cameraToClipMatrix * vec4(cameraSpacePosition, 1.0);
-	cameraSpaceNormal = normalize(normalModelToCameraMatrix * normal);
+	
+	mat3 modelToTangent = mat3(tangent, bitangent, normal);
+	mat3 cameraToTangent = modelToTangent * normalCameraToModelMatrix;
+	
+	cameraSpaceTangent = cameraToTangent[0];
+	cameraSpaceBitangent = cameraToTangent[1];
+	cameraSpaceNormal = cameraToTangent[2];
 
-	colorCoord = texCoord;
+	normalCoord = texCoord;
 }

Tut 18 Bumpy Textures/data/square_normal.png

Added
New image

Tut 18 Bumpy Textures/data/square_tan.xml

+<?xml version="1.0" encoding="UTF-8"?>
+<mesh xmlns="http://www.arcsynthesis.com/gltut/mesh">
+	<attribute index="0" type="float" size="3">
+		1 1 0
+		-0.999999 1 0
+		-1 -0.999999 0
+		1 -1 0</attribute>
+	<attribute index="2" type="float" size="3">
+		0 0 1
+		0 0 1
+		0 0 1
+		0 0 1</attribute>
+	<attribute index="3" type="float" size="3">
+		1 -1.58946e-007 0
+		1 0 0
+		1 -1.58946e-007 0
+		1 -4.76837e-007 0</attribute>
+	<attribute index="4" type="float" size="3">
+		3.17892e-007 1 -0
+		4.76837e-007 1 -0
+		3.17892e-007 1 -0
+		-0 1 -0</attribute>
+	<attribute index="5" type="float" size="2">
+		1 1
+		0 1
+		0 0
+		1 0</attribute>
+	<indices cmd="triangles" type="ushort">
+		2 1 0
+		3 2 0</indices>
+</mesh>

framework/Scene.cpp

 		GLenum m_texType;
 	};
 
+	struct ExtraProgUniforms
+	{
+		GLint normalMatLoc;
+		GLint invNormalMatLoc;
+	};
+
 	class SceneProgram
 	{
 	public:
-		SceneProgram(GLuint programObj, GLint matrixLoc, GLint normalMatLoc)
+		SceneProgram(GLuint programObj, GLint matrixLoc, ExtraProgUniforms extras)
 			: m_programObj(programObj)
 			, m_matrixLoc(matrixLoc)
-			, m_normalMatLoc(normalMatLoc)
+			, m_extras(extras)
 		{}
 
 		~SceneProgram()
 		}
 
 		GLint GetMatrixLoc() const {return m_matrixLoc;}
-		GLint GetNormalMatLoc() const {return m_normalMatLoc;}
+		GLint GetNormalMatLoc() const {return m_extras.normalMatLoc;}
+		GLint GetInvNormalMatLoc() const {return m_extras.invNormalMatLoc;}
 
 		void UseProgram() const {glUseProgram(m_programObj);}
 
 	private:
 		GLuint m_programObj;
 		GLint m_matrixLoc;
-		GLint m_normalMatLoc;
+		ExtraProgUniforms m_extras;
 	};
 
 	struct Transform
 				glUniformMatrix3fv(theVariant.pProg->GetNormalMatLoc(), 1, GL_FALSE,
 					glm::value_ptr(normMat));
 			}
+			if(theVariant.pProg->GetInvNormalMatLoc() != -1)
+			{
+				glm::mat3 invNormMat = glm::inverse(glm::mat3(glm::transpose(glm::inverse(objMat))));
+				glUniformMatrix3fv(theVariant.pProg->GetInvNormalMatLoc(), 1, GL_FALSE,
+					glm::value_ptr(invNormMat));
+			}
 
 			std::for_each(m_binders.begin(), m_binders.end(), BindBinder(theVariant.pProg->GetProgram()));
 			for(size_t texIx = 0; texIx < theVariant.texBindings.size(); ++texIx)
 
 			//Optional.
 			const xml_attribute<> *pNormalMatrixNode = progNode.first_attribute("normal-model-to-camera");
+			const xml_attribute<> *pInvNormalMatrixNode = progNode.first_attribute("normal-camera-to-model");
 			const xml_attribute<> *pGeometryShaderNode = progNode.first_attribute("geom");
 
 			std::string name = make_string(*pNameNode);
 					" in program " + name);
 			}
 
-			GLint normalMatLoc = -1;
+			ExtraProgUniforms extras;
+			extras.normalMatLoc = -1;
 			if(pNormalMatrixNode)
 			{
 				matrixName = make_string(*pNormalMatrixNode);
-				normalMatLoc = glGetUniformLocation(program, matrixName.c_str());
-				if(normalMatLoc == -1)
+				extras.normalMatLoc = glGetUniformLocation(program, matrixName.c_str());
+				if(extras.normalMatLoc == -1)
 				{
 					glDeleteProgram(program);
 					throw std::runtime_error("Could not find the normal matrix uniform " + matrixName +
 				}
 			}
 
-			m_progs[name] = new SceneProgram(program, matrixLoc, normalMatLoc);
+			extras.invNormalMatLoc = -1;
+			if(pInvNormalMatrixNode)
+			{
+				matrixName = make_string(*pInvNormalMatrixNode);
+				extras.invNormalMatLoc = glGetUniformLocation(program, matrixName.c_str());
+				if(extras.invNormalMatLoc == -1)
+				{
+					glDeleteProgram(program);
+					throw std::runtime_error("Could not find the inverse normal matrix uniform " + matrixName +
+						" in program " + name);
+				}
+			}
+
+			m_progs[name] = new SceneProgram(program, matrixLoc, extras);
 
 			ReadProgramContents(program, progNode);
 		}