Jason McKesson avatar Jason McKesson committed 3d0fe9b

Tutorial 1 text complete. Principle coding of tutorial 2 complete.

Comments (0)

Files changed (14)

Tut 01 Hello Triangle/premake4.lua

+
+dofile("../framework/framework.lua")
+
+SetupSolution("Tutorial1")
+SetupProject("Tutorial1", "tut1.cpp")

Tut 01 Hello Triangle/tut1.cpp

+
+#include <string>
+#include <vector>
+#include <glloader/gl_3_2_comp.h>
+#include <GL/freeglut.h>
+
+
+GLuint CreateShader(GLenum eShaderType, const std::string &strShaderFile)
+{
+	GLuint shader = glCreateShader(eShaderType);
+	const char *strFileData = strShaderFile.c_str();
+	glShaderSource(shader, 1, &strFileData, NULL);
+
+	glCompileShader(shader);
+
+	GLint status;
+	glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+	if (status == GL_FALSE)
+	{
+		GLint infoLogLength;
+		glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
+		glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);
+
+		const char *strShaderType = NULL;
+		switch(eShaderType)
+		{
+		case GL_VERTEX_SHADER: strShaderType = "vertex"; break;
+		case GL_GEOMETRY_SHADER: strShaderType = "geometry"; break;
+		case GL_FRAGMENT_SHADER: strShaderType = "fragment"; break;
+		}
+
+		fprintf(stderr, "Compile failure in %s shader:\n%s\n", strShaderType, strInfoLog);
+		delete[] strInfoLog;
+	}
+
+	return shader;
+}
+
+GLuint CreateProgram(const std::vector<GLuint> &shaderList)
+{
+	GLuint program = glCreateProgram();
+
+	for(size_t iLoop = 0; iLoop < shaderList.size(); iLoop++)
+		glAttachShader(program, shaderList[iLoop]);
+
+	glLinkProgram(program);
+
+	GLint status;
+	glGetProgramiv (program, GL_LINK_STATUS, &status);
+	if (status == GL_FALSE)
+	{
+		GLint infoLogLength;
+		glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
+		glGetProgramInfoLog(program, infoLogLength, NULL, strInfoLog);
+		fprintf(stderr, "Linker failure: %s\n", strInfoLog);
+		delete[] strInfoLog;
+	}
+
+	return program;
+}
+
+GLuint theProgram;
+GLuint positionAttrib;
+
+const std::string strVertexShader(
+	"#version 150\n"
+	"in vec4 position;\n"
+	"void main()\n"
+	"{\n"
+	"   gl_Position = position;\n"
+	"}\n"
+);
+
+const std::string strFragmentShader(
+	"#version 150\n"
+	"out vec4 outputColor;\n"
+	"void main()\n"
+	"{\n"
+	"   outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n"
+	"}\n"
+);
+
+void InitializeProgram()
+{
+	std::vector<GLuint> shaderList;
+
+	shaderList.push_back(CreateShader(GL_VERTEX_SHADER, strVertexShader));
+	shaderList.push_back(CreateShader(GL_FRAGMENT_SHADER, strFragmentShader));
+
+	theProgram = CreateProgram(shaderList);
+
+	positionAttrib = glGetAttribLocation(theProgram, "position");
+}
+
+const float vertexPositions[] = {
+	0.75f, 0.75f, 0.0f, 1.0f,
+	0.75f, -0.75f, 0.0f, 1.0f,
+	-0.75f, -0.75f, 0.0f, 1.0f,
+};
+
+GLuint positionBufferObject;
+GLuint vao;
+
+
+void InitializeVertexBuffer()
+{
+	glGenBuffers(1, &positionBufferObject);
+
+	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
+	glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
+	glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+//Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
+void init()
+{
+	InitializeProgram();
+	InitializeVertexBuffer();
+
+	glGenVertexArrays(1, &vao);
+	glBindVertexArray(vao);
+}
+
+//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);
+	glClear(GL_COLOR_BUFFER_BIT);
+
+	glUseProgram(theProgram);
+
+	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
+	glEnableVertexAttribArray(positionAttrib);
+	glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
+
+	glDrawArrays(GL_TRIANGLES, 0, 3);
+
+	glDisableVertexAttribArray(positionAttrib);
+	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)
+{
+	glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+}
+
+//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:
+		  glutLeaveMainLoop();
+		  break;
+	}
+}
+
+

Tut 02 OpenGLs Moving Triangle/data/tut2c.vert

+#version 150
+
+in vec4 position;
+uniform float loopDuration;
+uniform float time;
+
+void main()
+{
+	float timeScale = 3.14159f * 2.0f / loopDuration;
+	
+	float currTime = mod(time, loopDuration);
+	vec4 totalOffset = vec4(
+		cos(currTime * timeScale) * 0.5f,
+		sin(currTime * timeScale) * 0.5f,
+		0.0f,
+		0.0f);
+
+	gl_Position = position + totalOffset;
+}

Tut 02 OpenGLs Moving Triangle/data/tut2d.frag

+#version 150
+
+out vec4 outputColor;
+
+uniform float fragLoopDuration;
+uniform float time;
+
+const vec4 firstColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
+const vec4 secondColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);
+
+void main()
+{
+	float currTime = mod(time, fragLoopDuration);
+	float currLerp = currTime / fragLoopDuration;
+	
+	outputColor = mix(firstColor, secondColor, currLerp);
+}

Tut 02 OpenGLs Moving Triangle/data/tut2d.vert

+#version 150
+
+in vec4 position;
+uniform float loopDuration;
+uniform float time;
+
+void main()
+{
+	float timeScale = 3.14159f * 2.0f / loopDuration;
+	
+	float currTime = mod(time, loopDuration);
+	vec4 totalOffset = vec4(
+		cos(currTime * timeScale) * 0.5f,
+		sin(currTime * timeScale) * 0.5f,
+		0.0f,
+		0.0f);
+
+	gl_Position = position + totalOffset;
+}

Tut 02 OpenGLs Moving Triangle/premake4.lua

+
+dofile("../framework/framework.lua")
+
+SetupSolution("Tutorial2")
+SetupProject("Tutorial2a", "tut2a.cpp")
+SetupProject("Tutorial2b", "tut2b.cpp")
+SetupProject("Tutorial2c", "tut2c.cpp")
+SetupProject("Tutorial2d", "tut2d.cpp")

Tut 02 OpenGLs Moving Triangle/tut2a.cpp

+
+#include <string>
+#include <vector>
+#include <math.h>
+#include <glloader/gl_3_2_comp.h>
+#include <GL/freeglut.h>
+
+#define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
+
+GLuint CreateShader(GLenum eShaderType, const std::string &strShaderFile)
+{
+	GLuint shader = glCreateShader(eShaderType);
+	const char *strFileData = strShaderFile.c_str();
+	glShaderSource(shader, 1, &strFileData, NULL);
+
+	glCompileShader(shader);
+
+	GLint status;
+	glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+	if (status == GL_FALSE)
+	{
+		GLint infoLogLength;
+		glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
+		glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);
+
+		const char *strShaderType = NULL;
+		switch(eShaderType)
+		{
+		case GL_VERTEX_SHADER: strShaderType = "vertex"; break;
+		case GL_GEOMETRY_SHADER: strShaderType = "geometry"; break;
+		case GL_FRAGMENT_SHADER: strShaderType = "fragment"; break;
+		}
+
+		fprintf(stderr, "Compile failure in %s shader:\n%s\n", strShaderType, strInfoLog);
+		delete[] strInfoLog;
+	}
+
+	return shader;
+}
+
+GLuint CreateProgram(const std::vector<GLuint> &shaderList)
+{
+	GLuint program = glCreateProgram();
+
+	for(size_t iLoop = 0; iLoop < shaderList.size(); iLoop++)
+		glAttachShader(program, shaderList[iLoop]);
+
+	glLinkProgram(program);
+
+	GLint status;
+	glGetProgramiv (program, GL_LINK_STATUS, &status);
+	if (status == GL_FALSE)
+	{
+		GLint infoLogLength;
+		glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
+		glGetProgramInfoLog(program, infoLogLength, NULL, strInfoLog);
+		fprintf(stderr, "Linker failure: %s\n", strInfoLog);
+		delete[] strInfoLog;
+	}
+
+	return program;
+}
+
+GLuint theProgram;
+GLuint positionAttrib;
+
+const std::string strVertexShader(
+	"#version 150\n"
+	"in vec4 position;\n"
+	"void main()\n"
+	"{\n"
+	"   gl_Position = position;\n"
+	"}\n"
+);
+
+const std::string strFragmentShader(
+	"#version 150\n"
+	"out vec4 outputColor;\n"
+	"void main()\n"
+	"{\n"
+	"   outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n"
+	"}\n"
+);
+
+void InitializeProgram()
+{
+	std::vector<GLuint> shaderList;
+
+	shaderList.push_back(CreateShader(GL_VERTEX_SHADER, strVertexShader));
+	shaderList.push_back(CreateShader(GL_FRAGMENT_SHADER, strFragmentShader));
+
+	theProgram = CreateProgram(shaderList);
+
+	positionAttrib = glGetAttribLocation(theProgram, "position");
+}
+
+const float vertexPositions[] = {
+	0.25f, 0.25f, 0.0f, 1.0f,
+	0.25f, -0.25f, 0.0f, 1.0f,
+	-0.25f, -0.25f, 0.0f, 1.0f,
+};
+
+GLuint positionBufferObject;
+GLuint vao;
+
+
+void InitializeVertexBuffer()
+{
+	glGenBuffers(1, &positionBufferObject);
+
+	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
+	glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STREAM_DRAW);
+	glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+//Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
+void init()
+{
+	InitializeProgram();
+	InitializeVertexBuffer();
+
+	glGenVertexArrays(1, &vao);
+	glBindVertexArray(vao);
+}
+
+
+void ComputePositionOffsets(float &fXOffset, float &fYOffset)
+{
+	const float fLoopDuration = 5.0f;
+	const float fScale = 3.14159f * 2.0f / fLoopDuration;
+
+	float fElapsedTime = glutGet(GLUT_ELAPSED_TIME) / 1000.0f;
+
+	float fCurrTimeThroughLoop = fmodf(fElapsedTime, fLoopDuration);
+
+	fYOffset = cosf(fCurrTimeThroughLoop * fScale) * 0.5f;
+	fXOffset = sinf(fCurrTimeThroughLoop * fScale) * 0.5f;
+}
+
+void AdjustVertexData(float fXOffset, float fYOffset)
+{
+	std::vector<float> fNewData(ARRAY_COUNT(vertexPositions));
+	memcpy(&fNewData[0], vertexPositions, sizeof(vertexPositions));
+
+	for(int iVertex = 0; iVertex < ARRAY_COUNT(vertexPositions); iVertex += 4)
+	{
+		fNewData[iVertex] += fXOffset;
+		fNewData[iVertex + 1] += fYOffset;
+	}
+
+	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
+	glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertexPositions), &fNewData[0]);
+	glBindBuffer(GL_ARRAY_BUFFER, 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.
+void display()
+{
+	float fXOffset = 0.0f, fYOffset = 0.0f;
+	ComputePositionOffsets(fXOffset, fYOffset);
+	AdjustVertexData(fXOffset, fYOffset);
+
+	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+	glClear(GL_COLOR_BUFFER_BIT);
+
+	glUseProgram(theProgram);
+
+	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
+	glEnableVertexAttribArray(positionAttrib);
+	glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
+
+	glDrawArrays(GL_TRIANGLES, 0, 3);
+
+	glDisableVertexAttribArray(positionAttrib);
+	glUseProgram(0);
+
+	glutSwapBuffers();
+	glutPostRedisplay();
+}
+
+//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)
+{
+	glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+}
+
+//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:
+		  glutLeaveMainLoop();
+		  break;
+	}
+}
+
+

Tut 02 OpenGLs Moving Triangle/tut2b.cpp

+
+#include <string>
+#include <vector>
+#include <math.h>
+#include <glloader/gl_3_2_comp.h>
+#include <GL/freeglut.h>
+
+#define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
+
+GLuint CreateShader(GLenum eShaderType, const std::string &strShaderFile)
+{
+	GLuint shader = glCreateShader(eShaderType);
+	const char *strFileData = strShaderFile.c_str();
+	glShaderSource(shader, 1, &strFileData, NULL);
+
+	glCompileShader(shader);
+
+	GLint status;
+	glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+	if (status == GL_FALSE)
+	{
+		GLint infoLogLength;
+		glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
+		glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);
+
+		const char *strShaderType = NULL;
+		switch(eShaderType)
+		{
+		case GL_VERTEX_SHADER: strShaderType = "vertex"; break;
+		case GL_GEOMETRY_SHADER: strShaderType = "geometry"; break;
+		case GL_FRAGMENT_SHADER: strShaderType = "fragment"; break;
+		}
+
+		fprintf(stderr, "Compile failure in %s shader:\n%s\n", strShaderType, strInfoLog);
+		delete[] strInfoLog;
+	}
+
+	return shader;
+}
+
+GLuint CreateProgram(const std::vector<GLuint> &shaderList)
+{
+	GLuint program = glCreateProgram();
+
+	for(size_t iLoop = 0; iLoop < shaderList.size(); iLoop++)
+		glAttachShader(program, shaderList[iLoop]);
+
+	glLinkProgram(program);
+
+	GLint status;
+	glGetProgramiv (program, GL_LINK_STATUS, &status);
+	if (status == GL_FALSE)
+	{
+		GLint infoLogLength;
+		glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
+		glGetProgramInfoLog(program, infoLogLength, NULL, strInfoLog);
+		fprintf(stderr, "Linker failure: %s\n", strInfoLog);
+		delete[] strInfoLog;
+	}
+
+	return program;
+}
+
+GLuint theProgram;
+GLuint positionAttrib;
+GLuint offsetLocation;
+
+const std::string strVertexShader(
+"#version 150\n"
+"in vec4 position;\n"
+"uniform vec2 offset;"
+"void main()\n"
+"{\n"
+"	vec4 totalOffset = vec4(offset.x, offset.y, 0.0, 0.0);\n"
+"   gl_Position = position + totalOffset;\n"
+"}\n"
+);
+
+const std::string strFragmentShader(
+"#version 150\n"
+"out vec4 outputColor;\n"
+"void main()\n"
+"{\n"
+"   outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n"
+"}\n"
+);
+
+void InitializeProgram()
+{
+	std::vector<GLuint> shaderList;
+
+	shaderList.push_back(CreateShader(GL_VERTEX_SHADER, strVertexShader));
+	shaderList.push_back(CreateShader(GL_FRAGMENT_SHADER, strFragmentShader));
+
+	theProgram = CreateProgram(shaderList);
+
+	positionAttrib = glGetAttribLocation(theProgram, "position");
+	offsetLocation = glGetUniformLocation(theProgram, "offset");
+}
+
+const float vertexPositions[] = {
+	0.25f, 0.25f, 0.0f, 1.0f,
+	0.25f, -0.25f, 0.0f, 1.0f,
+	-0.25f, -0.25f, 0.0f, 1.0f,
+};
+
+GLuint positionBufferObject;
+GLuint vao;
+
+
+void InitializeVertexBuffer()
+{
+	glGenBuffers(1, &positionBufferObject);
+
+	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
+	glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STREAM_DRAW);
+	glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+//Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
+void init()
+{
+	InitializeProgram();
+	InitializeVertexBuffer();
+
+	glGenVertexArrays(1, &vao);
+	glBindVertexArray(vao);
+}
+
+
+void ComputePositionOffsets(float &fXOffset, float &fYOffset)
+{
+	const float fLoopDuration = 5.0f;
+	const float fScale = 3.14159f * 2.0f / fLoopDuration;
+
+	float fElapsedTime = glutGet(GLUT_ELAPSED_TIME) / 1000.0f;
+
+	float fCurrTimeThroughLoop = fmodf(fElapsedTime, fLoopDuration);
+
+	fXOffset = cosf(fCurrTimeThroughLoop * fScale) * 0.5f;
+	fYOffset = sinf(fCurrTimeThroughLoop * fScale) * 0.5f;
+}
+
+//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()
+{
+	float fXOffset = 0.0f, fYOffset = 0.0f;
+	ComputePositionOffsets(fXOffset, fYOffset);
+
+	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+	glClear(GL_COLOR_BUFFER_BIT);
+
+	glUseProgram(theProgram);
+
+	glUniform2f(offsetLocation, fXOffset, fYOffset);
+
+	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
+	glEnableVertexAttribArray(positionAttrib);
+	glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
+
+	glDrawArrays(GL_TRIANGLES, 0, 3);
+
+	glDisableVertexAttribArray(positionAttrib);
+	glUseProgram(0);
+
+	glutSwapBuffers();
+	glutPostRedisplay();
+}
+
+//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)
+{
+	glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+}
+
+//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:
+		glutLeaveMainLoop();
+		break;
+	}
+}
+
+

Tut 02 OpenGLs Moving Triangle/tut2c.cpp

+
+#include <string>
+#include <vector>
+#include <fstream>
+#include <sstream>
+#include <math.h>
+#include <glloader/gl_3_2_comp.h>
+#include <GL/freeglut.h>
+
+#define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
+
+GLuint CreateShader(GLenum eShaderType, const std::string &strShaderFile)
+{
+	GLuint shader = glCreateShader(eShaderType);
+	const char *strFileData = strShaderFile.c_str();
+	glShaderSource(shader, 1, &strFileData, NULL);
+
+	glCompileShader(shader);
+
+	GLint status;
+	glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+	if (status == GL_FALSE)
+	{
+		GLint infoLogLength;
+		glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
+		glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);
+
+		const char *strShaderType = NULL;
+		switch(eShaderType)
+		{
+		case GL_VERTEX_SHADER: strShaderType = "vertex"; break;
+		case GL_GEOMETRY_SHADER: strShaderType = "geometry"; break;
+		case GL_FRAGMENT_SHADER: strShaderType = "fragment"; break;
+		}
+
+		fprintf(stderr, "Compile failure in %s shader:\n%s\n", strShaderType, strInfoLog);
+		delete[] strInfoLog;
+	}
+
+	return shader;
+}
+
+GLuint LoadShader(GLenum eShaderType, const std::string &strShaderFilename)
+{
+	std::string strFilename = "data\\" + strShaderFilename;
+	std::ifstream shaderFile(strFilename.c_str());
+	std::stringstream shaderData;
+	shaderData << shaderFile.rdbuf();
+	shaderFile.close();
+
+	return CreateShader(eShaderType, shaderData.str());
+}
+
+GLuint CreateProgram(const std::vector<GLuint> &shaderList)
+{
+	GLuint program = glCreateProgram();
+
+	for(size_t iLoop = 0; iLoop < shaderList.size(); iLoop++)
+		glAttachShader(program, shaderList[iLoop]);
+
+	glLinkProgram(program);
+
+	GLint status;
+	glGetProgramiv (program, GL_LINK_STATUS, &status);
+	if (status == GL_FALSE)
+	{
+		GLint infoLogLength;
+		glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
+		glGetProgramInfoLog(program, infoLogLength, NULL, strInfoLog);
+		fprintf(stderr, "Linker failure: %s\n", strInfoLog);
+		delete[] strInfoLog;
+	}
+
+	return program;
+}
+
+GLuint theProgram;
+GLuint positionAttrib;
+GLuint elapsedTimeUniform;
+
+const std::string strFragmentShader(
+"#version 150\n"
+"out vec4 outputColor;\n"
+"void main()\n"
+"{\n"
+"   outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n"
+"}\n"
+);
+
+void InitializeProgram()
+{
+	std::vector<GLuint> shaderList;
+
+	shaderList.push_back(LoadShader(GL_VERTEX_SHADER, "tut2c.vert"));
+	shaderList.push_back(CreateShader(GL_FRAGMENT_SHADER, strFragmentShader));
+
+	theProgram = CreateProgram(shaderList);
+
+	positionAttrib = glGetAttribLocation(theProgram, "position");
+	elapsedTimeUniform = glGetUniformLocation(theProgram, "time");
+
+	GLuint loopDurationUnf = glGetUniformLocation(theProgram, "loopDuration");
+	glUseProgram(theProgram);
+	glUniform1f(loopDurationUnf, 5.0f);
+	glUseProgram(0);
+}
+
+const float vertexPositions[] = {
+	0.25f, 0.25f, 0.0f, 1.0f,
+	0.25f, -0.25f, 0.0f, 1.0f,
+	-0.25f, -0.25f, 0.0f, 1.0f,
+};
+
+GLuint positionBufferObject;
+GLuint vao;
+
+
+void InitializeVertexBuffer()
+{
+	glGenBuffers(1, &positionBufferObject);
+
+	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
+	glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STREAM_DRAW);
+	glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+//Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
+void init()
+{
+	InitializeProgram();
+	InitializeVertexBuffer();
+
+	glGenVertexArrays(1, &vao);
+	glBindVertexArray(vao);
+}
+
+//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);
+	glClear(GL_COLOR_BUFFER_BIT);
+
+	glUseProgram(theProgram);
+
+	glUniform1f(elapsedTimeUniform, glutGet(GLUT_ELAPSED_TIME) / 1000.0f);
+
+	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
+	glEnableVertexAttribArray(positionAttrib);
+	glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
+
+	glDrawArrays(GL_TRIANGLES, 0, 3);
+
+	glDisableVertexAttribArray(positionAttrib);
+	glUseProgram(0);
+
+	glutSwapBuffers();
+	glutPostRedisplay();
+}
+
+//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)
+{
+	glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+}
+
+//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:
+		glutLeaveMainLoop();
+		break;
+	}
+}
+
+

Tut 02 OpenGLs Moving Triangle/tut2d.cpp

+
+#include <string>
+#include <vector>
+#include <fstream>
+#include <sstream>
+#include <math.h>
+#include <glloader/gl_3_2_comp.h>
+#include <GL/freeglut.h>
+
+#define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
+
+GLuint CreateShader(GLenum eShaderType, const std::string &strShaderFile)
+{
+	GLuint shader = glCreateShader(eShaderType);
+	const char *strFileData = strShaderFile.c_str();
+	glShaderSource(shader, 1, &strFileData, NULL);
+
+	glCompileShader(shader);
+
+	GLint status;
+	glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+	if (status == GL_FALSE)
+	{
+		GLint infoLogLength;
+		glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
+		glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);
+
+		const char *strShaderType = NULL;
+		switch(eShaderType)
+		{
+		case GL_VERTEX_SHADER: strShaderType = "vertex"; break;
+		case GL_GEOMETRY_SHADER: strShaderType = "geometry"; break;
+		case GL_FRAGMENT_SHADER: strShaderType = "fragment"; break;
+		}
+
+		fprintf(stderr, "Compile failure in %s shader:\n%s\n", strShaderType, strInfoLog);
+		delete[] strInfoLog;
+	}
+
+	return shader;
+}
+
+GLuint LoadShader(GLenum eShaderType, const std::string &strShaderFilename)
+{
+	std::string strFilename = "data\\" + strShaderFilename;
+	std::ifstream shaderFile(strFilename.c_str());
+	std::stringstream shaderData;
+	shaderData << shaderFile.rdbuf();
+	shaderFile.close();
+
+	return CreateShader(eShaderType, shaderData.str());
+}
+
+GLuint CreateProgram(const std::vector<GLuint> &shaderList)
+{
+	GLuint program = glCreateProgram();
+
+	for(size_t iLoop = 0; iLoop < shaderList.size(); iLoop++)
+		glAttachShader(program, shaderList[iLoop]);
+
+	glLinkProgram(program);
+
+	GLint status;
+	glGetProgramiv (program, GL_LINK_STATUS, &status);
+	if (status == GL_FALSE)
+	{
+		GLint infoLogLength;
+		glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
+		glGetProgramInfoLog(program, infoLogLength, NULL, strInfoLog);
+		fprintf(stderr, "Linker failure: %s\n", strInfoLog);
+		delete[] strInfoLog;
+	}
+
+	return program;
+}
+
+GLuint theProgram;
+GLuint positionAttrib;
+GLuint elapsedTimeUniform;
+
+const std::string strFragmentShader(
+"#version 150\n"
+"out vec4 outputColor;\n"
+"void main()\n"
+"{\n"
+"   outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n"
+"}\n"
+);
+
+void InitializeProgram()
+{
+	std::vector<GLuint> shaderList;
+
+	shaderList.push_back(LoadShader(GL_VERTEX_SHADER, "tut2d.vert"));
+	shaderList.push_back(LoadShader(GL_FRAGMENT_SHADER, "tut2d.frag"));
+
+	theProgram = CreateProgram(shaderList);
+
+	positionAttrib = glGetAttribLocation(theProgram, "position");
+	elapsedTimeUniform = glGetUniformLocation(theProgram, "time");
+
+	GLuint loopDurationUnf = glGetUniformLocation(theProgram, "loopDuration");
+	GLuint fragLoopDurUnf = glGetUniformLocation(theProgram, "fragLoopDuration");
+
+
+	glUseProgram(theProgram);
+	glUniform1f(loopDurationUnf, 5.0f);
+	glUniform1f(fragLoopDurUnf, 10.0f);
+	glUseProgram(0);
+}
+
+const float vertexPositions[] = {
+	0.25f, 0.25f, 0.0f, 1.0f,
+	0.25f, -0.25f, 0.0f, 1.0f,
+	-0.25f, -0.25f, 0.0f, 1.0f,
+};
+
+GLuint positionBufferObject;
+GLuint vao;
+
+
+void InitializeVertexBuffer()
+{
+	glGenBuffers(1, &positionBufferObject);
+
+	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
+	glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STREAM_DRAW);
+	glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+//Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
+void init()
+{
+	InitializeProgram();
+	InitializeVertexBuffer();
+
+	glGenVertexArrays(1, &vao);
+	glBindVertexArray(vao);
+}
+
+//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);
+	glClear(GL_COLOR_BUFFER_BIT);
+
+	glUseProgram(theProgram);
+
+	glUniform1f(elapsedTimeUniform, glutGet(GLUT_ELAPSED_TIME) / 1000.0f);
+
+	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
+	glEnableVertexAttribArray(positionAttrib);
+	glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
+
+	glDrawArrays(GL_TRIANGLES, 0, 3);
+
+	glDisableVertexAttribArray(positionAttrib);
+	glUseProgram(0);
+
+	glutSwapBuffers();
+	glutPostRedisplay();
+}
+
+//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)
+{
+	glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+}
+
+//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:
+		glutLeaveMainLoop();
+		break;
+	}
+}
+
+

Tut1 Hello Triangle/premake4.lua

-
-dofile("../framework/framework.lua")
-
-SetupSolution("Tutorial1")
-SetupProject("Tutorial1", "tut1.cpp")

Tut1 Hello Triangle/tut1.cpp

-
-#include <string>
-#include <vector>
-#include <glloader/gl_3_2_comp.h>
-#include <GL/freeglut.h>
-
-
-GLuint CreateShader(GLenum eShaderType, const std::string &strShaderFile)
-{
-	GLuint shader = glCreateShader(eShaderType);
-	const char *strFileData = strShaderFile.c_str();
-	glShaderSource(shader, 1, &strFileData, NULL);
-
-	glCompileShader(shader);
-
-	GLint status;
-	glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
-	if (status == GL_FALSE)
-	{
-		GLint infoLogLength;
-		glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
-
-		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
-		glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);
-
-		const char *strShaderType = NULL;
-		switch(eShaderType)
-		{
-		case GL_VERTEX_SHADER: strShaderType = "vertex"; break;
-		case GL_GEOMETRY_SHADER: strShaderType = "geometry"; break;
-		case GL_FRAGMENT_SHADER: strShaderType = "fragment"; break;
-		}
-
-		fprintf(stderr, "Compile failure in %s shader:\n%s\n", strShaderType, strInfoLog);
-		delete[] strInfoLog;
-	}
-
-	return shader;
-}
-
-GLuint CreateProgram(const std::vector<GLuint> &shaderList)
-{
-	GLuint program = glCreateProgram();
-
-	for(size_t iLoop = 0; iLoop < shaderList.size(); iLoop++)
-		glAttachShader(program, shaderList[iLoop]);
-
-	glLinkProgram(program);
-
-	GLint status;
-	glGetProgramiv (program, GL_LINK_STATUS, &status);
-	if (status == GL_FALSE)
-	{
-		GLint infoLogLength;
-		glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
-
-		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
-		glGetProgramInfoLog(program, infoLogLength, NULL, strInfoLog);
-		fprintf(stderr, "Linker failure: %s\n", strInfoLog);
-		delete[] strInfoLog;
-	}
-
-	return program;
-}
-
-GLuint theProgram;
-GLuint positionAttrib;
-
-const std::string strVertexShader(
-	"#version 150\n"
-	"in vec4 position;\n"
-	"void main()\n"
-	"{\n"
-	"   gl_Position = position;\n"
-	"}\n"
-);
-
-const std::string strFragmentShader(
-	"#version 150\n"
-	"out vec4 outputColor;\n"
-	"void main()\n"
-	"{\n"
-	"   outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n"
-	"}\n"
-);
-
-void InitializeProgram()
-{
-	std::vector<GLuint> shaderList;
-
-	shaderList.push_back(CreateShader(GL_VERTEX_SHADER, strVertexShader));
-	shaderList.push_back(CreateShader(GL_FRAGMENT_SHADER, strFragmentShader));
-
-	theProgram = CreateProgram(shaderList);
-
-	positionAttrib = glGetAttribLocation(theProgram, "position");
-}
-
-const float vertexPositions[] = {
-	0.75f, 0.75f, 0.0f, 1.0f,
-	0.75f, -0.75f, 0.0f, 1.0f,
-	-0.75f, -0.75f, 0.0f, 1.0f,
-};
-
-GLuint positionBufferObject;
-GLuint vao;
-
-
-void InitializeVertexBuffer()
-{
-	glGenBuffers(1, &positionBufferObject);
-
-	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
-	glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
-	glBindBuffer(GL_ARRAY_BUFFER, 0);
-}
-
-//Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
-void init()
-{
-	InitializeProgram();
-	InitializeVertexBuffer();
-
-	glGenVertexArrays(1, &vao);
-	glBindVertexArray(vao);
-}
-
-//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);
-	glClear(GL_COLOR_BUFFER_BIT);
-
-	glUseProgram(theProgram);
-
-	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
-	glEnableVertexAttribArray(positionAttrib);
-	glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
-
-	glDrawArrays(GL_TRIANGLES, 0, 3);
-
-	glDisableVertexAttribArray(positionAttrib);
-	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)
-{
-	glViewport(0, 0, (GLsizei) w, (GLsizei) h);
-}
-
-//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:
-		  glutLeaveMainLoop();
-		  break;
-	}
-}
-
-

Tutorial Documents/Outline.xml

                 <para>Multi-buffering (SwapBuffers).</para>
             </listitem>
         </itemizedlist>
+        <para>Tutorial sub-files:</para>
+        <orderedlist>
+            <listitem>
+                <para>Use BufferSubData to update the triangle's position manually.</para>
+            </listitem>
+            <listitem>
+                <para>Use uniforms and a vertex shader to move the triangle's position. The position
+                    offset comes directly from the user.</para>
+            </listitem>
+            <listitem>
+                <para>Use a vertex shader that generates the position offset based solely on a time
+                    from start.</para>
+            </listitem>
+            <listitem>
+                <para>Use the time value from the last example in the fragment shader to do some
+                    color interpolation.</para>
+            </listitem>
+        </orderedlist>
     </section>
     <section>
         <title>Playing with Colors</title>

Tutorial Documents/Tutorial1/Tutorial 1.xml

                 case, we change it to match the full available area; without this function, resizing
                 the window would have no effect on the rendering. Also, make note of the fact that
                 we make no effort to keep the aspect ratio constant.</para>
+            <para>Recall that window coordinates are in a lower-left coordinate system. So the point
+                (0, 0) is the bottom left of the window. This function takes the bottom left
+                position as the first two coordinates, and the width and height of the viewport
+                rectangle as the other two coordinates.</para>
             <para>Once in window coordinates, OpenGL can now take these 3 vertices and scan-convert
                 it into a series of fragments. In order to do this however, OpenGL must decide what
                 the list of vertices represents.</para>
             cleanup function. But part of it is also due to the nature of OpenGL itself. In a simple
             example such as this, there is no need to delete anything. OpenGL will clean up its own
             assets when OpenGL is shut down as part of window deactivation.</para>
+        <para>It is generally good form to delete objects that you create before shutting down
+            OpenGL. And you certainly should do it if you encapsulate objects in C++ objects, such
+            that destructors will delete the OpenGL objects. But it isn't strictly necessary.</para>
     </section>
     <section>
         <title>In Review</title>
             how to compile and link shaders, how to pass some basic vertex data to OpenGL, and how
             to render a triangle.</para>
         <section>
-            <title>Things to Try</title>
-            <para>Feel free to modify the tutorial and try any of the following:</para>
+            <title>Further Study</title>
+            <para>Even with a simple tutorial like this, there are many things to play around with
+                and investigate.</para>
             <itemizedlist>
                 <listitem>
                     <para>Change the color value set by the fragment shader to different values. Use
                 </listitem>
                 <listitem>
                     <para>Change the positions of the vertex data. Keep position values in the [-1,
-                        1] range, then see what happens when triangles go outside this range.</para>
+                        1] range, then see what happens when triangles go outside this range. Notice
+                        what happens when you change the Z value of the positions (note: nothing
+                        should happen). Keep W at 1.0 for now.</para>
                 </listitem>
                 <listitem>
                     <para>Change the values that <function>reshape</function> gives to
                     <para>Change the clear color, using values in the range [0, 1]. Notice how this
                         interacts with changes to the viewport.</para>
                 </listitem>
+                <listitem>
+                    <para>Add another 3 vertices to the list, and change the number of vertices sent
+                        in the <function>glDrawArrays</function> call from 3 to 6. Add more and play
+                        with them.</para>
+                </listitem>
             </itemizedlist>
         </section>
         <section>
                     <glossterm>glEnableVertexAttribArray, glDisableVertexAttribArray,
                         glVertexAttribPointer</glossterm>
                     <glossdef>
-                        <para/>
+                        <para>These functions control vertex attribute arrays.
+                                <function>glEnableVertexAttribArray</function> activates the given
+                            attribute index, <function>glDisableVertexAttribArray</function>
+                            deactivates the given attribute index, and
+                                <function>glVertexAttribPointer</function> defines the format and
+                            source location (buffer object) of the vertex data.</para>
                     </glossdef>
                 </glossentry>
                 <glossentry>
                     <glossterm>glDrawArrays</glossterm>
                     <glossdef>
-                        <para/>
+                        <para>This function initiates rendering, using the currently active vertex
+                            attributes and the current program object (among other state). It causes
+                            a number of vertices to be pulled from the attribute arrays in
+                            order.</para>
                     </glossdef>
                 </glossentry>
                 <glossentry>
                     <glossterm>glViewport</glossterm>
                     <glossdef>
-                        <para/>
+                        <para>This function defines the current viewport transform. It defines as a
+                            region of the window, specified by the bottom-left position and a
+                            width/height.</para>
                     </glossdef>
                 </glossentry>
                 <glossentry>
                     <glossterm>glCreateShader, glShaderSource, glCompileShader</glossterm>
                     <glossdef>
-                        <para/>
+                        <para>These functions create a working shader object.
+                                <function>glCreateShader</function> simply creates an empty shader
+                            object of a particular shader stage. <function>glShaderSource</function>
+                            sets strings into that object; multiple calls to this function simply
+                            overwrite the previously set strings.
+                                <function>glCompileShader</function> causes the shader object to be
+                            compiled with the previously set strings.</para>
                     </glossdef>
                 </glossentry>
                 <glossentry>
                     <glossterm>glCreateProgram, glAttachShader, glLinkProgram</glossterm>
                     <glossdef>
-                        <para/>
+                        <para>These functions create a working program object.
+                                <function>glCreateProgram</function> creates an empty program
+                            object. <function>glAttachShader</function> attaches a shader object to
+                            that program. Multiple calls attach multiple shader objects.
+                                <function>glLinkProgram</function> links all of the previously
+                            attached shaders into a complete program.</para>
                     </glossdef>
                 </glossentry>
                 <glossentry>
                     <glossterm>glUseProgram</glossterm>
                     <glossdef>
-                        <para/>
+                        <para>This function causes the given program to become the current program.
+                            All rendering taking place after this call will use this program for the
+                            various shader stages. If the program 0 is given, then no program is
+                            current.</para>
                     </glossdef>
                 </glossentry>
                 <glossentry>
                     <glossterm>glGetAttribLocation</glossterm>
                     <glossdef>
-                        <para/>
+                        <para>This function retrieves the attribute index of a named attribute. It
+                            takes the program to find the attribute in, and the name of the input
+                            variable of the vertex shader that the user is looking for the attribute
+                            index to.</para>
                     </glossdef>
                 </glossentry>
             </glosslist>
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.