| 
					
				 | 
			
			
				@@ -1,38 +1,113 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <GL/glew.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <iostream> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <type_traits> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "utils/Array.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "wrapper/GL.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool GL::checkAndPrintError(const char* message) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static_assert(std::is_same<GL::Shader, GLuint>::value, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              "shader has invalid type"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static_assert(std::is_same<GL::Program, GLuint>::value, "p has invalid type"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static_assert(std::is_same<char, GLchar>::value, "char has invalid type"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static_assert(std::is_same<int, GLint>::value, "int has invalid type"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static_assert(std::is_same<float, GLfloat>::value, "float has invalid type"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static_assert(std::is_same<GL::ShaderType, GLenum>::value, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              "shader type has invalid type"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static_assert(std::is_same<GL::Texture, GLuint>::value, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              "texture has invalid type"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static_assert(std::is_same<GL::Framebuffer, GLuint>::value, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              "framebuffer has invalid type"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static_assert(std::is_same<GL::ColorAttachment, GLenum>::value, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              "color attachment has invalid type"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static_assert(std::is_same<GL::VertexArray, GLuint>::value, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              "vertex array has invalid type"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static_assert(std::is_same<GL::Buffer, GLuint>::value, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              "buffer has invalid type"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::ShaderType GL::VERTEX_SHADER = GL_VERTEX_SHADER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::ShaderType GL::FRAGMENT_SHADER = GL_FRAGMENT_SHADER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::ShaderType GL::GEOMETRY_SHADER = GL_GEOMETRY_SHADER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::Attribute::Attribute(int count, int size, int type, bool normalized) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    : count(count), size(size), type(type), normalized(normalized) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::Attribute GL::Attribute::newFloat(int count) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return GL::Attribute(count, sizeof(float), GL_FLOAT, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::Attribute GL::Attribute::newColor(int count) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return GL::Attribute(count, sizeof(float), GL_FLOAT, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::Attribute GL::Attribute::newDummy() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return GL::Attribute(0, 0, -1, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool GL::Attribute::isDummy() const { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return type == -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int GL::Attribute::getSize() const { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return count * size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::TextureFormat::TextureFormat(int internalformat, int format, int type) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    : internalformat(internalformat), format(format), type(type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::TextureFormat GL::TextureFormat::color8(int channels) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    switch(channels) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 1: return TextureFormat(GL_RED, GL_RED, GL_UNSIGNED_BYTE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 2: return TextureFormat(GL_RG, GL_RG, GL_UNSIGNED_BYTE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 3: return TextureFormat(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 4: return TextureFormat(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    std::cout << channels << " is not a valid amount of channels\n"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return unknown(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::TextureFormat GL::TextureFormat::float16(int channels) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    switch(channels) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 1: return TextureFormat(GL_R16F, GL_RED, GL_FLOAT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 2: return TextureFormat(GL_RG16F, GL_RG, GL_FLOAT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 3: return TextureFormat(GL_RGB16F, GL_RGB, GL_FLOAT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 4: return TextureFormat(GL_RGBA16F, GL_RGBA, GL_FLOAT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    std::cout << channels << " is not a valid amount of channels\n"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return unknown(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::TextureFormat GL::TextureFormat::float32(int channels) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    switch(channels) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 1: return TextureFormat(GL_R32F, GL_RED, GL_FLOAT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 2: return TextureFormat(GL_RG32F, GL_RG, GL_FLOAT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 3: return TextureFormat(GL_RGB32F, GL_RGB, GL_FLOAT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 4: return TextureFormat(GL_RGBA32F, GL_RGBA, GL_FLOAT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    std::cout << channels << " is not a valid amount of channels\n"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return unknown(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::TextureFormat GL::TextureFormat::depth16() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return TextureFormat(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_FLOAT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::TextureFormat GL::TextureFormat::depth32() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return TextureFormat(GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_FLOAT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::TextureFormat GL::TextureFormat::unknown() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return TextureFormat(-1, -1, -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool GL::printError(const char* message) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GLenum error = glGetError(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    switch(error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        case GL_NO_ERROR: return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        case GL_INVALID_ENUM: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            std::cout << message << ": an unacceptable value is specified for an enumerated argument\n"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        case GL_INVALID_VALUE: std::cout << message << ": a numeric argument is out of range\n"; break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        case GL_INVALID_OPERATION: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            std::cout << message << ": the specified operation is not allowed in the current state\n"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        case GL_INVALID_FRAMEBUFFER_OPERATION: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            std::cout << message << ": the framebuffer object is not complete\n"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        case GL_OUT_OF_MEMORY: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            std::cout << message << ": there is not enough memory left to execute the command\n"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        case GL_STACK_UNDERFLOW: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            std::cout << message 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      << ": an attempt has been made to perform an operation that would cause an internal stack to " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                         "underflow\n"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        case GL_STACK_OVERFLOW: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            std::cout << message 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      << ": an attempt has been made to perform an operation that would cause an internal stack to " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                         "overflow\n"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        default: std::cout << message << ": unknown OpenGL error '" << error << "'\n"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(error != GL_NO_ERROR) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        std::cout << message << ": " << gluErrorString(error) << '\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void GL::enableDepthTesting() { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -47,7 +122,7 @@ void GL::bindMainFramebuffer() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     glBindFramebuffer(GL_FRAMEBUFFER, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-void GL::clearFramebuffer() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::clear() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -63,4 +138,248 @@ void GL::disableBlending() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void GL::setViewport(int width, int height) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     glViewport(0, 0, width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::vertexAttribPointer(int index, const Attribute& a, int stride, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                             int offset) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glVertexAttribPointer(index, a.count, a.type, a.normalized, stride, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          static_cast<char*>(0) + offset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glEnableVertexAttribArray(index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::Program GL::createProgram() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return glCreateProgram(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::attachShader(Program p, Shader s) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glAttachShader(p, s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::linkProgram(Program p) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glLinkProgram(p); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool GL::logLinkerError(Program p) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GLint linked; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glGetProgramiv(p, GL_LINK_STATUS, &linked); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(!linked) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Array<char, 1024> log; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        glGetProgramInfoLog(p, log.getLength(), nullptr, log.begin()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        std::cout << "linker log: " << log.begin() << "\n"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::deleteShader(Shader s) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glDeleteShader(s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::deleteProgram(Program p) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glDeleteProgram(p); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::Shader GL::createShader(ShaderType type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return glCreateShader(type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::compileShader(Shader s, const char* code) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glShaderSource(s, 1, &code, nullptr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glCompileShader(s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool GL::logCompileError(Shader s) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GLint compiled; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glGetShaderiv(s, GL_COMPILE_STATUS, &compiled); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(!compiled) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Array<char, 1024> log; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        glGetShaderInfoLog(s, log.getLength(), nullptr, log.begin()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        std::cout << "compiler log: " << log.begin() << "\n"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::useProgram(Program p) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glUseProgram(p); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::setMatrix(Program p, const char* name, const float* data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glUniformMatrix4fv(glGetUniformLocation(p, name), 1, GL_TRUE, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::setInt(Program p, const char* name, int data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glUniform1i(glGetUniformLocation(p, name), data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::setFloat(Program p, const char* name, float data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glUniform1f(glGetUniformLocation(p, name), data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::set2Float(Program p, const char* name, const float* data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glUniform2fv(glGetUniformLocation(p, name), 1, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::set3Float(Program p, const char* name, const float* data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glUniform3fv(glGetUniformLocation(p, name), 1, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::set4Float(Program p, const char* name, const float* data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glUniform4fv(glGetUniformLocation(p, name), 1, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::texImage2D(const TextureFormat& tf, int width, int height, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    const void* data, int level) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glTexImage2D(GL_TEXTURE_2D, level, tf.internalformat, width, height, 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 tf.format, tf.type, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::Texture GL::genTexture() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Texture t; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glGenTextures(1, &t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return t; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::deleteTexture(Texture t) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glDeleteTextures(1, &t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::setNearFilter2D() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::setMipMapNearFilter2D() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    GL_NEAREST_MIPMAP_LINEAR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::setLinearFilter2D() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::setMipMapLinearFilter2D() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    GL_LINEAR_MIPMAP_LINEAR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::setClampWrap2D() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::setRepeatWrap2D() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::bindTexture2D(Texture t) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glBindTexture(GL_TEXTURE_2D, t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::activeTexture(int index) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glActiveTexture(GL_TEXTURE0 + index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::generateMipmap2D(int maxLevels) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, maxLevels); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glGenerateMipmap(GL_TEXTURE_2D); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::deleteFramebuffers(Framebuffer fb) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glDeleteFramebuffers(1, &fb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::Framebuffer GL::genFramebuffer() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Framebuffer fb; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glGenFramebuffers(1, &fb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return fb; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::bindFramebuffer(Framebuffer fb) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glBindFramebuffer(GL_FRAMEBUFFER, fb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::framebufferDepthTexture2D(Texture t) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                           t, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::ColorAttachment GL::framebufferColorTexture2D(Texture t, int index) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GLenum c = GL_COLOR_ATTACHMENT0 + index; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glFramebufferTexture2D(GL_FRAMEBUFFER, c, GL_TEXTURE_2D, t, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::drawBuffers(int length, ColorAttachment* c) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glDrawBuffers(length, c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool GL::printFramebufferError() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GLenum error = glCheckFramebufferStatus(GL_FRAMEBUFFER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(error == GL_FRAMEBUFFER_COMPLETE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        std::cout << "framebuffer error: " << error << '\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::VertexArray GL::genVertexArray() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    VertexArray va; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glGenVertexArrays(1, &va); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return va; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+GL::Buffer GL::genBuffer() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Buffer b; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glGenBuffers(1, &b); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return b; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::deleteBuffer(Buffer b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glDeleteBuffers(1, &b); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::deleteVertexArray(VertexArray va) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glDeleteVertexArrays(1, &va); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::bindVertexArray(VertexArray va) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glBindVertexArray(va); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::bindBuffer(Buffer b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glBindBuffer(GL_ARRAY_BUFFER, b); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::bufferDataStatic(int size, const void* data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::bufferDataStream(int size, const void* data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glBufferData(GL_ARRAY_BUFFER, size, data, GL_STREAM_DRAW); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::bufferDataDynamic(int size, const void* data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glBufferData(GL_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::bufferSubData(int offset, int size, const void* data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glBufferSubData(GL_ARRAY_BUFFER, offset, size, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::drawTriangles(int offset, int vertices) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glDrawArrays(GL_TRIANGLES, offset, vertices); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::drawTriangleStrip(int offset, int vertices) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glDrawArrays(GL_TRIANGLE_STRIP, offset, vertices); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void GL::drawPoints(int offset, int vertices) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glDrawArrays(GL_POINTS, offset, vertices); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |