Jason McKesson avatar Jason McKesson committed f2e7385

Tut16: Gamma ramp code done.

Comments (0)

Files changed (5)

Tut 16 Gamma and Textures/GammaRamp.cpp

 #include <stdio.h>
 #include <string.h>
 #include <glload/gl_3_3.h>
+#include <glm/glm.hpp>
+#include <glimg/glimg.h>
 #include <GL/freeglut.h>
 #include "../framework/framework.h"
+#include "../framework/MatrixStack.h"
+#include "../framework/directories.h"
 
-GLuint theProgram;
-GLuint elapsedTimeUniform;
+const int g_projectionBlockIndex = 0;
+const int g_gammaRampTextureUnit = 0;
+
+GLuint g_noGammaProgram = 0;
+GLuint g_gammaProgram = 0;
 
 void InitializeProgram()
 {
+	GLuint vertexShader = Framework::LoadShader(GL_VERTEX_SHADER, "screenCoords.vert");
 	std::vector<GLuint> shaderList;
 
-	shaderList.push_back(Framework::LoadShader(GL_VERTEX_SHADER, "calcOffset.vert"));
-	shaderList.push_back(Framework::LoadShader(GL_FRAGMENT_SHADER, "calcColor.frag"));
+	shaderList.push_back(vertexShader);
+	shaderList.push_back(Framework::LoadShader(GL_FRAGMENT_SHADER, "textureNoGamma.frag"));
 
-	theProgram = Framework::CreateProgram(shaderList);
+	g_noGammaProgram = Framework::CreateProgram(shaderList);
+	glDeleteShader(shaderList.back());
 
-	elapsedTimeUniform = glGetUniformLocation(theProgram, "time");
+	shaderList.pop_back();
+	shaderList.push_back(Framework::LoadShader(GL_FRAGMENT_SHADER, "textureGamma.frag"));
 
-	GLuint loopDurationUnf = glGetUniformLocation(theProgram, "loopDuration");
-	GLuint fragLoopDurUnf = glGetUniformLocation(theProgram, "fragLoopDuration");
+	g_gammaProgram = Framework::CreateProgram(shaderList);
+	glDeleteShader(shaderList.back());
+	glDeleteShader(vertexShader);
 
+	GLuint projectionBlock = glGetUniformBlockIndex(g_noGammaProgram, "Projection");
+	glUniformBlockBinding(g_noGammaProgram, projectionBlock, g_projectionBlockIndex);
 
-	glUseProgram(theProgram);
-	glUniform1f(loopDurationUnf, 5.0f);
-	glUniform1f(fragLoopDurUnf, 10.0f);
+	GLuint colorTextureUnif = glGetUniformLocation(g_noGammaProgram, "colorTexture");
+	glUseProgram(g_noGammaProgram);
+	glUniform1i(colorTextureUnif, g_gammaRampTextureUnit);
+	glUseProgram(0);
+
+	projectionBlock = glGetUniformBlockIndex(g_gammaProgram, "Projection");
+	glUniformBlockBinding(g_gammaProgram, projectionBlock, g_projectionBlockIndex);
+
+	colorTextureUnif = glGetUniformLocation(g_gammaProgram, "colorTexture");
+	glUseProgram(g_gammaProgram);
+	glUniform1i(colorTextureUnif, g_gammaRampTextureUnit);
 	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,
+const GLushort vertexData[] = {
+	 90, 80,	0,		0,
+	 90, 16,	0,		65535,
+	410, 80,	65535,	0,
+	410, 16,	65535,	65535,
+
+	 90, 176,	0,		0,
+	 90, 112,	0,		65535,
+	410, 176,	65535,	0,
+	410, 112,	65535,	65535,
 };
 
-GLuint positionBufferObject;
-GLuint vao;
+GLuint g_dataBufferObject;
+GLuint g_vao;
 
 
-void InitializeVertexBuffer()
+void InitializeVertexData()
 {
-	glGenBuffers(1, &positionBufferObject);
+	glGenBuffers(1, &g_dataBufferObject);
 
-	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
-	glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STREAM_DRAW);
+	glBindBuffer(GL_ARRAY_BUFFER, g_dataBufferObject);
+	glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
+
+	glGenVertexArrays(1, &g_vao);
+
+	glBindVertexArray(g_vao);
+	glBindBuffer(GL_ARRAY_BUFFER, g_dataBufferObject);
+	glEnableVertexAttribArray(0);
+	glVertexAttribPointer(0, 2, GL_UNSIGNED_SHORT, false, 8, (void*)0);
+	glEnableVertexAttribArray(5);
+	glVertexAttribPointer(5, 2, GL_UNSIGNED_SHORT, true, 8, (void*)4);
+
+	glBindVertexArray(0);
 	glBindBuffer(GL_ARRAY_BUFFER, 0);
 }
 
+struct ProjectionBlock
+{
+	glm::mat4 cameraToClipMatrix;
+};
+
+GLuint g_projectionUniformBuffer;
+GLuint g_textures[2];
+GLuint g_samplerObj;
+
+void LoadTextures()
+{
+	glGenTextures(2, g_textures);
+
+	std::string filename(LOCAL_FILE_DIR);
+	filename += "gamma_ramp.png";
+
+	try
+	{
+		std::auto_ptr<glimg::ImageSet> pImageSet(glimg::loaders::stb::LoadFromFile(filename.c_str()));
+
+		glimg::SingleImage image = pImageSet->GetImage(0, 0, 0);
+		glimg::Dimensions dims = image.GetDimensions();
+
+		glimg::OpenGLPixelTransferParams pxTrans = glimg::GetUploadFormatType(pImageSet->GetFormat(), 0);
+
+		glBindTexture(GL_TEXTURE_2D, g_textures[0]);
+
+		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, dims.width, dims.height, 0,
+			pxTrans.format, pxTrans.type, image.GetImageData());
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, pImageSet->GetMipmapCount() - 1);
+		
+		glBindTexture(GL_TEXTURE_2D, g_textures[1]);
+		glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8, dims.width, dims.height, 0,
+			pxTrans.format, pxTrans.type, image.GetImageData());
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, pImageSet->GetMipmapCount() - 1);
+
+		glBindTexture(GL_TEXTURE_2D, 0);
+	}
+	catch(std::exception &e)
+	{
+		printf("%s\n", e.what());
+		throw;
+	}
+
+	glGenSamplers(1, &g_samplerObj);
+	glSamplerParameteri(g_samplerObj, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+	glSamplerParameteri(g_samplerObj, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+	glSamplerParameteri(g_samplerObj, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glSamplerParameteri(g_samplerObj, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+}
+
 //Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
 void init()
 {
 	InitializeProgram();
-	InitializeVertexBuffer();
+	InitializeVertexData();
+	LoadTextures();
 
-	glGenVertexArrays(1, &vao);
-	glBindVertexArray(vao);
+	//Setup our Uniform Buffers
+	glGenBuffers(1, &g_projectionUniformBuffer);
+	glBindBuffer(GL_UNIFORM_BUFFER, g_projectionUniformBuffer);
+	glBufferData(GL_UNIFORM_BUFFER, sizeof(ProjectionBlock), NULL, GL_DYNAMIC_DRAW);
+
+	glBindBufferRange(GL_UNIFORM_BUFFER, g_projectionBlockIndex, g_projectionUniformBuffer,
+		0, sizeof(ProjectionBlock));
+
+	glBindBuffer(GL_UNIFORM_BUFFER, 0);
 }
 
+bool g_useGammaCorrect[2] = {false, false};
+
 //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);
+	glClearColor(0.0f, 0.5f, 0.3f, 0.0f);
 	glClear(GL_COLOR_BUFFER_BIT);
 
-	glUseProgram(theProgram);
+	glActiveTexture(GL_TEXTURE0 + g_gammaRampTextureUnit);
+	glBindTexture(GL_TEXTURE_2D, g_textures[g_useGammaCorrect[0] ? 1 : 0]);
 
-	glUniform1f(elapsedTimeUniform, glutGet(GLUT_ELAPSED_TIME) / 1000.0f);
+	glBindVertexArray(g_vao);
 
-	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
-	glEnableVertexAttribArray(0);
-	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
+	glUseProgram(g_noGammaProgram);
+	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 
-	glDrawArrays(GL_TRIANGLES, 0, 3);
+	glBindTexture(GL_TEXTURE_2D, g_textures[g_useGammaCorrect[1] ? 1 : 0]);
 
-	glDisableVertexAttribArray(0);
+	glUseProgram(g_gammaProgram);
+	glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
+
+	glBindVertexArray(0);
 	glUseProgram(0);
 
+	glActiveTexture(GL_TEXTURE0 + g_gammaRampTextureUnit);
+	glBindTexture(GL_TEXTURE_2D, 0);
+
 	glutSwapBuffers();
 	glutPostRedisplay();
 }
 //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.Translate(-1.0f, 1.0f, 0.0f);
+	persMatrix.Scale(2.0f / w, -2.0f / h, 1.0f);
+
+	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.
 	case 27:
 		glutLeaveMainLoop();
 		return;
+	case '1':
+		g_useGammaCorrect[0] = !g_useGammaCorrect[0];
+		if(g_useGammaCorrect[0])
+			printf("Top:\tsRGB texture.\n");
+		else
+			printf("Top:\tlinear texture.\n");
+		break;
+	case '2':
+		g_useGammaCorrect[1] = !g_useGammaCorrect[1];
+		if(g_useGammaCorrect[1])
+			printf("Bottom:\tsRGB texture.\n");
+		else
+			printf("Bottom:\tlinear texture.\n");
+		break;
+
+	case 32:
+		break;
 	}
 }
 
 
-unsigned int defaults(unsigned int displayMode, int &width, int &height) {return displayMode;}
+unsigned int defaults(unsigned int displayMode, int &width, int &height) {height = 192; return displayMode;}
Add a comment to this file

Tut 16 Gamma and Textures/data/gamma_ramp.png

Old
Old image
New
New image

Tut 16 Gamma and Textures/data/screenCoords.vert

 #version 330
 
-layout(location = 0) in vec4 position;
-uniform float loopDuration;
-uniform float time;
+layout(std140) uniform;
+
+layout(location = 0) in vec2 position;
+layout(location = 5) in vec2 texCoord;
+
+layout(std140) uniform Projection
+{
+	mat4 cameraToClipMatrix;
+};
+
+out vec2 colorCoord;
 
 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;
+	gl_Position = cameraToClipMatrix * vec4(position, 0.0, 1.0);
+	colorCoord = texCoord;
 }

Tut 16 Gamma and Textures/data/textureGamma.frag

-#version 150
+#version 330
+
+in vec2 colorCoord;
+
+uniform sampler2D colorTexture;
 
 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);
+	vec4 gamma = vec4(1.0 / 2.2);
+	gamma.w = 1.0;
+	outputColor = pow(texture(colorTexture, colorCoord), gamma);
 }

Tut 16 Gamma and Textures/data/textureNoGamma.frag

-#version 150
+#version 330
+
+in vec2 colorCoord;
+
+uniform sampler2D colorTexture;
 
 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);
+	outputColor = texture(colorTexture, colorCoord);
 }
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.