diff --git a/examples/debug/main.cpp b/examples/debug/main.cpp
index cfc51c8..90efdc0 100644
--- a/examples/debug/main.cpp
+++ b/examples/debug/main.cpp
@@ -74,6 +74,7 @@ int main(int argc, char** argv)
 
 		oglu::ClearScreen(GL_COLOR_BUFFER_BIT, oglu::Color(0.29f, 0.13f, 0.23f));
 
+		shader->SetUniform("ourColor", &oglu::Color::Blue);
 		shader->Use();
 		square.BindAndDraw();
 
diff --git a/examples/debug/shaders/fragmentShader.frag b/examples/debug/shaders/fragmentShader.frag
index 2fc8143..3073fb0 100644
--- a/examples/debug/shaders/fragmentShader.frag
+++ b/examples/debug/shaders/fragmentShader.frag
@@ -3,7 +3,9 @@ in vec3 oCol;
 
 out vec4 FragColor;
 
+uniform vec4 ourColor;
+
 void main()
 {
-	FragColor = vec4(oCol, 1.0f);
+	FragColor = vec4(oCol, 1.0f) + ourColor;
 }
\ No newline at end of file
diff --git a/include/shader.hpp b/include/shader.hpp
index c389630..203d9b9 100644
--- a/include/shader.hpp
+++ b/include/shader.hpp
@@ -6,6 +6,8 @@
 
 namespace oglu
 {
+	class Color;
+
 	class OGLU_API Shader
 	{
 	public:
@@ -14,6 +16,112 @@ namespace oglu
 
 		void Use();
 
+		GLint GetUniformLocation(const GLchar* name);
+
+#pragma region Uniforms
+		void SetUniform(const GLchar* name,	GLfloat v0);
+		void SetUniform(GLint location,		GLfloat v0);
+			 
+		void SetUniform(const GLchar* name,	GLfloat v0, GLfloat v1);
+		void SetUniform(GLint location,		GLfloat v0, GLfloat v1);
+			 
+		void SetUniform(const GLchar* name,	GLfloat v0, GLfloat v1, GLfloat v2);
+		void SetUniform(GLint location,		GLfloat v0, GLfloat v1, GLfloat v2);
+			 
+		void SetUniform(const GLchar* name,	GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+		void SetUniform(GLint location,		GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+			 
+		void SetUniform(const GLchar* name,	GLint v0);
+		void SetUniform(GLint location,		GLint v0);
+			  
+		void SetUniform(const GLchar* name,	GLint v0, GLint v1);
+		void SetUniform(GLint location,		GLint v0, GLint v1);
+			  
+		void SetUniform(const GLchar* name,	GLint v0, GLint v1, GLint v2);
+		void SetUniform(GLint location,		GLint v0, GLint v1, GLint v2);
+			 
+		void SetUniform(const GLchar* name,	GLint v0, GLint v1, GLint v2, GLint v3);
+		void SetUniform(GLint location,		GLint v0, GLint v1, GLint v2, GLint v3);
+
+		void SetUniform(const GLchar* name,	GLuint v0);
+		void SetUniform(GLint location,		GLuint v0);
+						
+		void SetUniform(const GLchar* name,	GLuint v0, GLuint v1);
+		void SetUniform(GLint location,		GLuint v0, GLuint v1);
+						
+		void SetUniform(const GLchar* name,	GLuint v0, GLuint v1, GLuint v2);
+		void SetUniform(GLint location,		GLuint v0, GLuint v1, GLuint v2);
+						
+		void SetUniform(const GLchar* name,	GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+		void SetUniform(GLint location,		GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+
+		void SetUniform(const GLchar* name, const Color* v0, bool ignoreAlpha = false);
+		void SetUniform(GLint location,		const Color* v0, bool ignoreAlpha = false);
+
+		void SetUniform1fv(const GLchar* name,	GLsizei count, const GLfloat* value);
+		void SetUniform1fv(GLint location,		GLsizei count, const GLfloat* value);
+						 
+		void SetUniform2fv(const GLchar* name,	GLsizei count, const GLfloat* value);
+		void SetUniform2fv(GLint location,		GLsizei count, const GLfloat* value);
+						 
+		void SetUniform3fv(const GLchar* name,	GLsizei count, const GLfloat* value);
+		void SetUniform3fv(GLint location,		GLsizei count, const GLfloat* value);
+						 
+		void SetUniform4fv(const GLchar* name,	GLsizei count, const GLfloat* value);
+		void SetUniform4fv(GLint location,		GLsizei count, const GLfloat* value);
+
+		void SetUniform1iv(const GLchar* name,	GLsizei count, const GLint* value);
+		void SetUniform1iv(GLint location,		GLsizei count, const GLint* value);
+						
+		void SetUniform2iv(const GLchar* name,	GLsizei count, const GLint* value);
+		void SetUniform2iv(GLint location,		GLsizei count, const GLint* value);
+						
+		void SetUniform3iv(const GLchar* name,	GLsizei count, const GLint* value);
+		void SetUniform3iv(GLint location,		GLsizei count, const GLint* value);
+						
+		void SetUniform4iv(const GLchar* name,	GLsizei count, const GLint* value);
+		void SetUniform4iv(GLint location,		GLsizei count, const GLint* value);
+
+		void SetUniform1uiv(const GLchar* name, GLsizei count, const GLuint* value);
+		void SetUniform1uiv(GLint location,		GLsizei count, const GLuint* value);
+						
+		void SetUniform2uiv(const GLchar* name, GLsizei count, const GLuint* value);
+		void SetUniform2uiv(GLint location,		GLsizei count, const GLuint* value);
+						
+		void SetUniform3uiv(const GLchar* name, GLsizei count, const GLuint* value);
+		void SetUniform3uiv(GLint location,		GLsizei count, const GLuint* value);
+						
+		void SetUniform4uiv(const GLchar* name,	GLsizei count, const GLuint* value);
+		void SetUniform4uiv(GLint location,		GLsizei count, const GLuint* value);
+
+		void SetUniformMatrix2fv(const GLchar* name,	GLsizei count, GLboolean transpose, const GLfloat* value);
+		void SetUniformMatrix2fv(GLint location,		GLsizei count, GLboolean transpose, const GLfloat* value);
+
+		void SetUniformMatrix3fv(const GLchar* name,	GLsizei count, GLboolean transpose, const GLfloat* value);
+		void SetUniformMatrix3fv(GLint location,		GLsizei count, GLboolean transpose, const GLfloat* value);
+
+		void SetUniformMatrix4fv(const GLchar* name,	GLsizei count, GLboolean transpose, const GLfloat* value);
+		void SetUniformMatrix4fv(GLint location,		GLsizei count, GLboolean transpose, const GLfloat* value);
+
+		void SetUniformMatrix2x3fv(const GLchar* name,	GLsizei count, GLboolean transpose, const GLfloat* value);
+		void SetUniformMatrix2x3fv(GLint location,		GLsizei count, GLboolean transpose, const GLfloat* value);
+
+		void SetUniformMatrix3x2fv(const GLchar* name,	GLsizei count, GLboolean transpose, const GLfloat* value);
+		void SetUniformMatrix3x2fv(GLint location,		GLsizei count, GLboolean transpose, const GLfloat* value);
+
+		void SetUniformMatrix2x4fv(const GLchar* name,	GLsizei count, GLboolean transpose, const GLfloat* value);
+		void SetUniformMatrix2x4fv(GLint location,		GLsizei count, GLboolean transpose, const GLfloat* value);
+
+		void SetUniformMatrix4x2fv(const GLchar* name,	GLsizei count, GLboolean transpose, const GLfloat* value);
+		void SetUniformMatrix4x2fv(GLint location,		GLsizei count, GLboolean transpose, const GLfloat* value);
+
+		void SetUniformMatrix3x4fv(const GLchar* name,	GLsizei count, GLboolean transpose, const GLfloat* value);
+		void SetUniformMatrix3x4fv(GLint location,		GLsizei count, GLboolean transpose, const GLfloat* value);
+
+		void SetUniformMatrix4x3fv(const GLchar* name,	GLsizei count, GLboolean transpose, const GLfloat* value);
+		void SetUniformMatrix4x3fv(GLint location,		GLsizei count, GLboolean transpose, const GLfloat* value);
+#pragma endregion Uniforms
+
 	private:
 		void LoadShaderSource(const char* filename, char** buffer);
 
diff --git a/src/shader.cpp b/src/shader.cpp
index 154ce85..9b1d041 100644
--- a/src/shader.cpp
+++ b/src/shader.cpp
@@ -5,6 +5,8 @@
 #include <algorithm>
 #include <iostream>
 
+#include <color.hpp>
+
 namespace oglu
 {
 	Shader::Shader(const char* vertexShaderFile, const char* fragmentShaderFile) :
@@ -73,6 +75,356 @@ namespace oglu
 		glUseProgram(program);
 	}
 
+	GLint Shader::GetUniformLocation(const GLchar* name)
+	{
+		return glGetUniformLocation(program, name);
+	}
+
+#pragma region Uniforms
+	void Shader::SetUniform(const GLchar* name, GLfloat v0)
+	{
+		glUniform1f(glGetUniformLocation(program, name), v0);
+	}
+
+	void Shader::SetUniform(GLint location, GLfloat v0)
+	{
+		glUniform1f(location, v0);
+	}
+
+	void Shader::SetUniform(const GLchar* name, GLfloat v0, GLfloat v1)
+	{
+		glUniform2f(glGetUniformLocation(program, name), v0, v1);
+	}
+
+	void Shader::SetUniform(GLint location, GLfloat v0, GLfloat v1)
+	{
+		glUniform2f(location, v0, v1);
+	}
+
+	void Shader::SetUniform(const GLchar* name, GLfloat v0, GLfloat v1, GLfloat v2)
+	{
+		glUniform3f(glGetUniformLocation(program, name), v0, v1, v2);
+	}
+
+	void Shader::SetUniform(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+	{
+		glUniform3f(location, v0, v1, v2);
+	}
+
+	void Shader::SetUniform(const GLchar* name, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+	{
+		glUniform4f(glGetUniformLocation(program, name), v0, v1, v2, v3);
+	}
+
+	void Shader::SetUniform(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+	{
+		glUniform4f(location, v0, v1, v2, v3);
+	}
+
+	void Shader::SetUniform(const GLchar* name, GLint v0)
+	{
+		glUniform1i(glGetUniformLocation(program, name), v0);
+	}
+
+	void Shader::SetUniform(GLint location, GLint v0)
+	{
+		glUniform1i(location, v0);
+	}
+
+	void Shader::SetUniform(const GLchar* name, GLint v0, GLint v1)
+	{
+		glUniform2i(glGetUniformLocation(program, name), v0, v1);
+	}
+
+	void Shader::SetUniform(GLint location, GLint v0, GLint v1)
+	{
+		glUniform2i(location, v0, v1);
+	}
+
+	void Shader::SetUniform(const GLchar* name, GLint v0, GLint v1, GLint v2)
+	{
+		glUniform3i(glGetUniformLocation(program, name), v0, v1, v2);
+	}
+
+	void Shader::SetUniform(GLint location, GLint v0, GLint v1, GLint v2)
+	{
+		glUniform3i(location, v0, v1, v2);
+	}
+
+	void Shader::SetUniform(const GLchar* name, GLint v0, GLint v1, GLint v2, GLint v3)
+	{
+		glUniform4i(glGetUniformLocation(program, name), v0, v1, v2, v3);
+	}
+
+	void Shader::SetUniform(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
+	{
+		glUniform4i(location, v0, v1, v2, v3);
+	}
+
+	void Shader::SetUniform(const GLchar* name, GLuint v0)
+	{
+		glUniform1ui(glGetUniformLocation(program, name), v0);
+	}
+
+	void Shader::SetUniform(GLint location, GLuint v0)
+	{
+		glUniform1ui(location, v0);
+	}
+
+	void Shader::SetUniform(const GLchar* name, GLuint v0, GLuint v1)
+	{
+		glUniform2ui(glGetUniformLocation(program, name), v0, v1);
+	}
+
+	void Shader::SetUniform(GLint location, GLuint v0, GLuint v1)
+	{
+		glUniform2ui(location, v0, v1);
+	}
+
+	void Shader::SetUniform(const GLchar* name, GLuint v0, GLuint v1, GLuint v2)
+	{
+		glUniform3ui(glGetUniformLocation(program, name), v0, v1, v2);
+	}
+
+	void Shader::SetUniform(GLint location, GLuint v0, GLuint v1, GLuint v2)
+	{
+		glUniform3ui(location, v0, v1, v2);
+	}
+
+	void Shader::SetUniform(const GLchar* name, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+	{
+		glUniform4ui(glGetUniformLocation(program, name), v0, v1, v2, v3);
+	}
+
+	void Shader::SetUniform(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+	{
+		glUniform4ui(location, v0, v1, v2, v3);
+	}
+
+	void Shader::SetUniform(const GLchar* name, const Color* v0, bool ignoreAlpha)
+	{
+		SetUniform(glGetUniformLocation(program, name), v0, ignoreAlpha);
+	}
+
+	void Shader::SetUniform(GLint location, const Color* v0, bool ignoreAlpha)
+	{
+		if (ignoreAlpha)
+			glUniform3f(location, v0->r, v0->g, v0->b);
+		else
+			glUniform4f(location, v0->r, v0->g, v0->b, v0->a);
+	}
+
+	void Shader::SetUniform1fv(const GLchar* name, GLsizei count, const GLfloat* value)
+	{
+		glUniform1fv(glGetUniformLocation(program, name), count, value);
+	}
+
+	void Shader::SetUniform1fv(GLint location, GLsizei count, const GLfloat* value)
+	{
+		glUniform1fv(location, count, value);
+	}
+
+	void Shader::SetUniform2fv(const GLchar* name, GLsizei count, const GLfloat* value)
+	{
+		glUniform2fv(glGetUniformLocation(program, name), count, value);
+	}
+
+	void Shader::SetUniform2fv(GLint location, GLsizei count, const GLfloat* value)
+	{
+		glUniform2fv(location, count, value);
+	}
+
+	void Shader::SetUniform3fv(const GLchar* name, GLsizei count, const GLfloat* value)
+	{
+		glUniform3fv(glGetUniformLocation(program, name), count, value);
+	}
+
+	void Shader::SetUniform3fv(GLint location, GLsizei count, const GLfloat* value)
+	{
+		glUniform3fv(location, count, value);
+	}
+
+	void Shader::SetUniform4fv(const GLchar* name, GLsizei count, const GLfloat* value)
+	{
+		glUniform4fv(glGetUniformLocation(program, name), count, value);
+	}
+
+	void Shader::SetUniform4fv(GLint location, GLsizei count, const GLfloat* value)
+	{
+		glUniform4fv(location, count, value);
+	}
+
+	void Shader::SetUniform1iv(const GLchar* name, GLsizei count, const GLint* value)
+	{
+		glUniform1iv(glGetUniformLocation(program, name), count, value);
+	}
+
+	void Shader::SetUniform1iv(GLint location, GLsizei count, const GLint* value)
+	{
+		glUniform1iv(location, count, value);
+	}
+
+	void Shader::SetUniform2iv(const GLchar* name, GLsizei count, const GLint* value)
+	{
+		glUniform2iv(glGetUniformLocation(program, name), count, value);
+	}
+
+	void Shader::SetUniform2iv(GLint location, GLsizei count, const GLint* value)
+	{
+		glUniform2iv(location, count, value);
+	}
+
+	void Shader::SetUniform3iv(const GLchar* name, GLsizei count, const GLint* value)
+	{
+		glUniform3iv(glGetUniformLocation(program, name), count, value);
+	}
+
+	void Shader::SetUniform3iv(GLint location, GLsizei count, const GLint* value)
+	{
+		glUniform3iv(location, count, value);
+	}
+
+	void Shader::SetUniform4iv(const GLchar* name, GLsizei count, const GLint* value)
+	{
+		glUniform4iv(glGetUniformLocation(program, name), count, value);
+	}
+
+	void Shader::SetUniform4iv(GLint location, GLsizei count, const GLint* value)
+	{
+		glUniform4iv(location, count, value);
+	}
+
+	void Shader::SetUniform1uiv(const GLchar* name, GLsizei count, const GLuint* value)
+	{
+		glUniform1uiv(glGetUniformLocation(program, name), count, value);
+	}
+
+	void Shader::SetUniform1uiv(GLint location, GLsizei count, const GLuint* value)
+	{
+		glUniform1uiv(location, count, value);
+	}
+
+	void Shader::SetUniform2uiv(const GLchar* name, GLsizei count, const GLuint* value)
+	{
+		glUniform2uiv(glGetUniformLocation(program, name), count, value);
+	}
+
+	void Shader::SetUniform2uiv(GLint location, GLsizei count, const GLuint* value)
+	{
+		glUniform2uiv(location, count, value);
+	}
+
+	void Shader::SetUniform3uiv(const GLchar* name, GLsizei count, const GLuint* value)
+	{
+		glUniform3uiv(glGetUniformLocation(program, name), count, value);
+	}
+
+	void Shader::SetUniform3uiv(GLint location, GLsizei count, const GLuint* value)
+	{
+		glUniform3uiv(location, count, value);
+	}
+
+	void Shader::SetUniform4uiv(const GLchar* name, GLsizei count, const GLuint* value)
+	{
+		glUniform4uiv(glGetUniformLocation(program, name), count, value);
+	}
+
+	void Shader::SetUniform4uiv(GLint location, GLsizei count, const GLuint* value)
+	{
+		glUniform4uiv(location, count, value);
+	}
+
+	void Shader::SetUniformMatrix2fv(const GLchar* name, GLsizei count, GLboolean transpose, const GLfloat* value)
+	{
+		glUniformMatrix2fv(glGetUniformLocation(program, name), count, transpose, value);
+	}
+
+	void Shader::SetUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+	{
+		glUniformMatrix2fv(location, count, transpose, value);
+	}
+
+	void Shader::SetUniformMatrix3fv(const GLchar* name, GLsizei count, GLboolean transpose, const GLfloat* value)
+	{
+		glUniformMatrix3fv(glGetUniformLocation(program, name), count, transpose, value);
+	}
+
+	void Shader::SetUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+	{
+		glUniformMatrix3fv(location, count, transpose, value);
+	}
+
+	void Shader::SetUniformMatrix4fv(const GLchar* name, GLsizei count, GLboolean transpose, const GLfloat* value)
+	{
+		glUniformMatrix4fv(glGetUniformLocation(program, name), count, transpose, value);
+	}
+
+	void Shader::SetUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+	{
+		glUniformMatrix4fv(location, count, transpose, value);
+	}
+
+	void Shader::SetUniformMatrix2x3fv(const GLchar* name, GLsizei count, GLboolean transpose, const GLfloat* value)
+	{
+		glUniformMatrix2x3fv(glGetUniformLocation(program, name), count, transpose, value);
+	}
+
+	void Shader::SetUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+	{
+		glUniformMatrix2x3fv(location, count, transpose, value);
+	}
+
+	void Shader::SetUniformMatrix3x2fv(const GLchar* name, GLsizei count, GLboolean transpose, const GLfloat* value)
+	{
+		glUniformMatrix3x2fv(glGetUniformLocation(program, name), count, transpose, value);
+	}
+
+	void Shader::SetUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+	{
+		glUniformMatrix3x2fv(location, count, transpose, value);
+	}
+
+	void Shader::SetUniformMatrix2x4fv(const GLchar* name, GLsizei count, GLboolean transpose, const GLfloat* value)
+	{
+		glUniformMatrix2x4fv(glGetUniformLocation(program, name), count, transpose, value);
+	}
+
+	void Shader::SetUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+	{
+		glUniformMatrix2x4fv(location, count, transpose, value);
+	}
+
+	void Shader::SetUniformMatrix4x2fv(const GLchar* name, GLsizei count, GLboolean transpose, const GLfloat* value)
+	{
+		glUniformMatrix4x2fv(glGetUniformLocation(program, name), count, transpose, value);
+	}
+
+	void Shader::SetUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+	{
+		glUniformMatrix4x2fv(location, count, transpose, value);
+	}
+
+	void Shader::SetUniformMatrix3x4fv(const GLchar* name, GLsizei count, GLboolean transpose, const GLfloat* value)
+	{
+		glUniformMatrix3x4fv(glGetUniformLocation(program, name), count, transpose, value);
+	}
+
+	void Shader::SetUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+	{
+		glUniformMatrix3x4fv(location, count, transpose, value);
+	}
+
+	void Shader::SetUniformMatrix4x3fv(const GLchar* name, GLsizei count, GLboolean transpose, const GLfloat* value)
+	{
+		glUniformMatrix4x3fv(glGetUniformLocation(program, name), count, transpose, value);
+	}
+
+	void Shader::SetUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+	{
+		glUniformMatrix4x3fv(location, count, transpose, value);
+	}
+#pragma endregion Uniforms
+
 	void Shader::LoadShaderSource(const char* filename, char** buffer)
 	{
 		std::ifstream file(filename);