Commits

Jason McKesson committed 8385bbc

Fixed mesh rendering. Added Tutorial 7 mesh generation and a basic project.

  • Participants
  • Parent commits 59e68e9

Comments (0)

Files changed (14)

File Documents/Build/highlighting/glsl-hl.xml

 		<keyword>sampler1D</keyword>
 		<keyword>sampler2D</keyword>
 		<keyword>sampler3D</keyword>
-		<keyword>samplerCube   </keyword>
+		<keyword>samplerCube</keyword>
 		<keyword>sampler1DShadow</keyword>
 		<keyword>sampler2DShadow</keyword>
 		<keyword>samplerCubeShadow</keyword>

File Test/data/mesh.xml

 <?xml version="1.0" encoding="UTF-8"?>
-<?oxygen RNGSchema="../Documents/meshFormat.rnc" type="compact"?>
+<?oxygen RNGSchema="../../Documents/meshFormat.rnc" type="compact"?>
 <mesh xmlns="http://www.arcsynthesis.com/gltut/mesh">
     <attribute index="0" type="float" size="4">
         0.75 0.75 0.0 1.0

File Tut 07 World in Motion/World Scene.cpp

+#include <string>
+#include <vector>
+#include <stack>
+#include <math.h>
+#include <glloader/gl_3_2_comp.h>
+#include <GL/freeglut.h>
+#include "../framework/framework.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*))))
+
+GLuint theProgram;
+
+GLuint modelToWorldMatrixUnif;
+GLuint worldToCameraMatrixUnif;
+GLuint cameraToClipMatrixUnif;
+
+glm::mat4 cameraToClipMatrix(0.0f);
+
+float CalcFrustumScale(float fFovDeg)
+{
+	const float degToRad = 3.14159f * 2.0f / 360.0f;
+	float fFovRad = fFovDeg * degToRad;
+	return 1.0f / tan(fFovRad / 2.0f);
+}
+
+const float fFrustumScale = CalcFrustumScale(45.0f);
+
+void InitializeProgram()
+{
+	std::vector<GLuint> shaderList;
+
+	shaderList.push_back(Framework::LoadShader(GL_VERTEX_SHADER, "PosColorWorldTransform.vert"));
+	shaderList.push_back(Framework::LoadShader(GL_FRAGMENT_SHADER, "ColorPassthrough.frag"));
+
+	theProgram = Framework::CreateProgram(shaderList);
+
+	modelToWorldMatrixUnif = glGetUniformLocation(theProgram, "modelToWorldMatrix");
+	worldToCameraMatrixUnif = glGetUniformLocation(theProgram, "worldToCameraMatrix");
+	cameraToClipMatrixUnif = glGetUniformLocation(theProgram, "cameraToClipMatrix");
+
+	float fzNear = 1.0f; float fzFar = 1000.0f;
+
+	cameraToClipMatrix[0].x = fFrustumScale;
+	cameraToClipMatrix[1].y = fFrustumScale;
+	cameraToClipMatrix[2].z = (fzFar + fzNear) / (fzNear - fzFar);
+	cameraToClipMatrix[2].w = -1.0f;
+	cameraToClipMatrix[3].z = (2 * fzFar * fzNear) / (fzNear - fzFar);
+
+	glm::mat4 worldMat(1.0f);
+
+	glUseProgram(theProgram);
+	glUniformMatrix4fv(cameraToClipMatrixUnif, 1, GL_FALSE, glm::value_ptr(cameraToClipMatrix));
+	glUniformMatrix4fv(worldToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(worldMat));
+	glUseProgram(0);
+}
+
+Framework::Mesh *g_pConeMesh = NULL;
+
+//Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
+void init()
+{
+	InitializeProgram();
+
+	try
+	{
+		g_pConeMesh = new Framework::Mesh("UnitCylinderTint.xml");
+	}
+	catch(std::exception &except)
+	{
+		printf(except.what());
+	}
+
+	glEnable(GL_CULL_FACE);
+	glCullFace(GL_BACK);
+	glFrontFace(GL_CW);
+
+	glEnable(GL_DEPTH_TEST);
+	glDepthMask(GL_TRUE);
+	glDepthFunc(GL_LEQUAL);
+	glDepthRange(0.0f, 1.0f);
+}
+
+static float g_fYAngle = 0.0f;
+static float g_fXAngle = 0.0f;
+
+//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()
+{
+	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+	glClearDepth(1.0f);
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+	if(g_pConeMesh)
+	{
+		Framework::MatrixStack theStack;
+		theStack.Translate(glm::vec3(0.0f, 0.0f, -4.0f));
+		theStack.RotateX(g_fXAngle);
+		theStack.RotateY(g_fYAngle);
+		glUseProgram(theProgram);
+		glUniformMatrix4fv(modelToWorldMatrixUnif, 1, GL_FALSE, glm::value_ptr(theStack.Top()));
+		g_pConeMesh->Render();
+		glUseProgram(0);
+	}
+
+	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)
+{
+	cameraToClipMatrix[0].x = fFrustumScale * (h / (float)w);
+	cameraToClipMatrix[1].y = fFrustumScale;
+
+	glUseProgram(theProgram);
+	glUniformMatrix4fv(cameraToClipMatrixUnif, 1, GL_FALSE, glm::value_ptr(cameraToClipMatrix));
+	glUseProgram(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_pConeMesh;
+		glutLeaveMainLoop();
+		break;
+	case 'w': g_fXAngle += 11.25f; break;
+	case 's': g_fXAngle -= 11.25f; break;
+	case 'a': g_fYAngle -= 11.25f; break;
+	case 'd': g_fYAngle += 11.25f; break;
+	case 32: g_fYAngle = 0.0f; break;
+	}
+	glutPostRedisplay();
+}
+
+

File Tut 07 World in Motion/data/ColorExactUniform.frag

+#version 330
+
+uniform vec4 baseColor;
+
+out vec4 outputColor;
+
+void main()
+{
+	outputColor = baseColor;
+}

File Tut 07 World in Motion/data/ColorMultUniform.frag

+#version 330
+
+smooth in vec4 interpColor;
+uniform vec4 baseColor;
+
+out vec4 outputColor;
+
+void main()
+{
+	outputColor = interpColor * baseColor;
+}

File Tut 07 World in Motion/data/ColorPassthrough.frag

+#version 330
+
+smooth in vec4 interpColor;
+
+out vec4 outputColor;
+
+void main()
+{
+	outputColor = interpColor;
+}

File Tut 07 World in Motion/data/GenCones.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 fan1 = {};
+local fan2 = {};
+
+positions[#positions + 1] = vmath.vec3(0.0, 0.866, 0.0);
+colors[#colors + 1] = vmath.vec4(1.0, 1.0, 1.0, 1.0);
+fan1[#fan1 + 1] = 0;
+
+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.9, 0.9, 1.0);
+local lowColor = vmath.vec4(0.5, 0.5, 0.5, 1.0)
+
+for iSeg = 0, (iSegCount - 1), 1 do
+	local iCurrAngle = iSeg * iAngle;
+
+	positions[#positions + 1] =
+		vmath.vec3(0.5 * math.cos(iCurrAngle), 0.0, 0.5 * math.sin(iCurrAngle));
+
+	fan1[#fan1 + 1] = iSeg + 1;
+
+	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
+end
+
+--Close the figure.
+fan1[#fan1 + 1] = fan1[2];
+
+
+fan2[#fan2 + 1] = (iSegCount) + 1;
+
+for iSeg = (iSegCount - 1), 0, -1 do
+	fan2[#fan2 + 1] = iSeg + 1;
+end
+
+--Close the figure.
+fan2[#fan2 + 1] = fan2[2];
+
+positions[#positions + 1] = vmath.vec3(0.0, 0.0, 0.0);
+colors[#colors + 1] = highColor;
+
+do
+	local writer = XmlWriter.XmlWriter("UnitConeTint.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("indices");
+			writer:AddAttribute("cmd", "tri-fan");
+			writer:AddAttribute("type", "ushort");
+			writer:AddText(table.concat(fan1, " "));
+		writer:PopElement();
+		writer:PushElement("indices");
+			writer:AddAttribute("cmd", "tri-fan");
+			writer:AddAttribute("type", "ushort");
+			writer:AddText(table.concat(fan2, " "));
+		writer:PopElement();
+	writer:PopElement();
+	writer:Close();
+end
+
+do
+	local writer = XmlWriter.XmlWriter("UnitCone.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("indices");
+			writer:AddAttribute("cmd", "tri-fan");
+			writer:AddAttribute("type", "ushort");
+			writer:AddText(table.concat(fan1, " "));
+		writer:PopElement();
+		writer:PushElement("indices");
+			writer:AddAttribute("cmd", "tri-fan");
+			writer:AddAttribute("type", "ushort");
+			writer:AddText(table.concat(fan2, " "));
+		writer:PopElement();
+	writer:PopElement();
+	writer:Close();
+end

File Tut 07 World in Motion/data/GenCylinders.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 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.9, 0.9, 1.0);
+local lowColor = vmath.vec4(0.5, 0.5, 0.5, 1.0)
+
+positions[#positions + 1] = vmath.vec3(0.0, 0.5, 0.0);
+colors[#colors + 1] = vmath.vec4(1.0, 1.0, 1.0, 1.0);
+topFan[#topFan + 1] = 0;
+botFan[#botFan + 1] = (iSegCount * 2) + 1;
+
+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));
+
+	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);
+	cylStrip[#cylStrip + 1] = 1 + (iSeg * 2);
+	cylStrip[#cylStrip + 1] = 1 + (iSeg * 2) + 1;
+end
+
+topFan[#topFan + 1] = topFan[2];
+botFan[#botFan + 1] = botFan[2];
+
+cylStrip[#cylStrip + 1] = cylStrip[1];
+cylStrip[#cylStrip + 1] = cylStrip[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);
+
+
+do
+	local writer = XmlWriter.XmlWriter("UnitCylinderTint.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("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
+
+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("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 07 World in Motion/data/GenPlane.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(0.5, 0.0, -0.5),
+	vmath.vec3(0.5, 0.0, 0.5),
+	vmath.vec3(-0.5, 0.0, 0.5),
+	vmath.vec3(-0.5, 0.0, -0.5),
+};
+
+local indices =
+{
+	vmath.vec3(0, 1, 2),
+	vmath.vec3(0, 2, 1),
+	vmath.vec3(2, 3, 0),
+	vmath.vec3(2, 0, 3),
+};
+
+do
+	local writer = XmlWriter.XmlWriter("UnitPlane.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("indices");
+			writer:AddAttribute("cmd", "triangles");
+			writer:AddAttribute("type", "ushort");
+			writer:AddText(GenStringFromArray(indices, true));
+		writer:PopElement();
+	writer:PopElement();
+	writer:Close();
+end

File Tut 07 World in Motion/data/PosColorWorldTransform.vert

+#version 330
+
+layout(location = 0) in vec4 position;
+layout(location = 1) in vec4 color;
+
+smooth out vec4 interpColor;
+
+uniform mat4 cameraToClipMatrix;
+uniform mat4 worldToCameraMatrix;
+uniform mat4 modelToWorldMatrix;
+
+void main()
+{
+	vec4 temp = modelToWorldMatrix * position;
+//	temp = worldToCameraMatrix * temp;
+	gl_Position = cameraToClipMatrix * temp;
+	interpColor = color;
+}

File Tut 07 World in Motion/data/PosOnlyWorldTransform.vert

+#version 330
+
+layout(location = 0) in vec4 position;
+
+uniform mat4 cameraToClipMatrix;
+uniform mat4 worldToCameraMatrix;
+uniform mat4 modelToWorldMatrix;
+
+void main()
+{
+	vec4 temp = modelToWorldMatrix * position;
+	temp = worldToCameraMatrix * temp;
+	gl_Position = cameraToClipMatrix * temp;
+}

File Tut 07 World in Motion/premake4.lua

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

File Tut 07 World in Motion/tutorials.lua

+
+SetupProject("Tut 07 World Scene", "World Scene.cpp",
+	"data/PosOnlyWorldTransform.vert",
+	"data/PosColorWorldTransform.vert",
+	"data/ColorPassthrough.frag",
+	"data/ColorMultUniform.frag",
+	"data/ColorExactUniform.frag")

File framework/framework.cpp

 	WRITE_ARRAY_FUNCDEF(bValue,		GLbyte,		WriteBytes);
 
 
+
 	namespace
 	{
 		const AttribType g_allAttributeTypes[] =
 				{
 					prim.start = (GLuint)indexStartLocs[iCurrIndexed];
 					prim.elemCount = (GLuint)indexData[iCurrIndexed].dataArray.size();
+					prim.eIndexDataType = indexData[iCurrIndexed].pAttribType->eGLType;
+					iCurrIndexed++;
 				}
 			}
 		}
 {
 	glutInit(&argc, argv);
 	glutInitDisplayMode (GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH | GLUT_STENCIL);
-	/* add command line argument "classic" for a pre-3.x context */
-	if ((argc != 2) || (strcmp (argv[1], "classic") != 0)) {
-		glutInitContextVersion (3, 3);
-		glutInitContextProfile(GLUT_CORE_PROFILE);
+	glutInitContextVersion (3, 3);
+	glutInitContextProfile(GLUT_CORE_PROFILE);
 #ifdef DEBUG
-		glutInitContextFlags(GLUT_DEBUG);
+	glutInitContextFlags(GLUT_DEBUG);
 #endif
-	}
 	glutInitWindowSize (500, 500); 
 	glutInitWindowPosition (300, 200);
 	glutCreateWindow (argv[0]);