aboutsummaryrefslogtreecommitdiff
path: root/apps/openmb/renderer/Shader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'apps/openmb/renderer/Shader.cpp')
-rw-r--r--apps/openmb/renderer/Shader.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/apps/openmb/renderer/Shader.cpp b/apps/openmb/renderer/Shader.cpp
new file mode 100644
index 0000000..a7c94e6
--- /dev/null
+++ b/apps/openmb/renderer/Shader.cpp
@@ -0,0 +1,137 @@
+#include "Shader.hpp"
+
+#define GLFW_INCLUDE_NONE
+#include <GLFW/glfw3.h>
+#ifdef __APPLE__
+#include <OpenGL/gl3.h>
+#endif
+#include <fstream>
+#include <iostream>
+#include <sstream>
+
+namespace renderer {
+Shader::Shader () : mID( 0 ) {}
+
+Shader::~Shader () {
+ if( mID ) {
+ glDeleteProgram( mID );
+ }
+}
+
+bool Shader::fromSource ( const std::string& vertexSrc, const std::string& fragmentSrc ) {
+ return compileShader( vertexSrc.c_str(), fragmentSrc.c_str() );
+}
+
+bool Shader::fromFiles ( const std::string& vertexPath, const std::string& fragmentPath ) {
+ std::string vs = readFile( vertexPath );
+ std::string fs = readFile( fragmentPath );
+ if( vs.empty() || fs.empty() ) {
+ return false;
+ }
+ return compileShader( vs.c_str(), fs.c_str() );
+}
+
+void Shader::use () const {
+ glUseProgram( mID );
+}
+
+unsigned int Shader::id () const {
+ return mID;
+}
+
+void Shader::setInt ( const std::string& name, int value ) const {
+ glUniform1i( glGetUniformLocation( mID, name.c_str() ), value );
+}
+
+void Shader::setFloat ( const std::string& name, float value ) const {
+ glUniform1f( glGetUniformLocation( mID, name.c_str() ), value );
+}
+
+void Shader::setVec3 ( const std::string& name, const glm::vec3& v ) const {
+ glUniform3f( glGetUniformLocation( mID, name.c_str() ), v.x, v.y, v.z );
+}
+
+void Shader::setVec2 ( const std::string& name, const glm::vec2& v ) const {
+ glUniform2f( glGetUniformLocation( mID, name.c_str() ), v.x, v.y );
+}
+
+void Shader::setMat4 ( const std::string& name, const glm::mat4& m ) const {
+ glUniformMatrix4fv( glGetUniformLocation( mID, name.c_str() ), 1, GL_FALSE, &m[0][0] );
+}
+
+bool Shader::compileShader ( const char* vSrc, const char* fSrc ) {
+ GLuint vert = glCreateShader( GL_VERTEX_SHADER );
+ glShaderSource( vert, 1, &vSrc, nullptr );
+ glCompileShader( vert );
+
+ GLint success = 0;
+ glGetShaderiv( vert, GL_COMPILE_STATUS, &success );
+ if( success == GL_FALSE ) {
+ GLint len = 0;
+ glGetShaderiv( vert, GL_INFO_LOG_LENGTH, &len );
+ std::string log( len, '\0' );
+ glGetShaderInfoLog( vert, len, &len, &log[0] );
+ std::cerr << "Vertex shader compile error:\n"
+ << log << std::endl;
+ std::cerr << "[Shader] Vertex shader ID = " << vert << std::endl;
+ glDeleteShader( vert );
+ return false;
+ }
+
+ GLuint frag = glCreateShader( GL_FRAGMENT_SHADER );
+
+ glShaderSource( frag, 1, &fSrc, nullptr );
+ glCompileShader( frag );
+
+ glGetShaderiv( frag, GL_COMPILE_STATUS, &success );
+ if( success == GL_FALSE ) {
+ GLint len = 0;
+ glGetShaderiv( frag, GL_INFO_LOG_LENGTH, &len );
+ std::string log( len, '\0' );
+ glGetShaderInfoLog( frag, len, &len, &log[0] );
+ std::cerr << "Fragment shader compile error:\n"
+ << log << std::endl;
+ glDeleteShader( frag );
+ glDeleteShader( vert );
+ return false;
+ }
+
+ mID = glCreateProgram();
+ glAttachShader( mID, vert );
+ glAttachShader( mID, frag );
+ glLinkProgram( mID );
+
+ glGetProgramiv( mID, GL_LINK_STATUS, &success );
+ if( success == GL_FALSE ) {
+ GLint len = 0;
+ glGetProgramiv( mID, GL_INFO_LOG_LENGTH, &len );
+ std::string log( len, '\0' );
+ glGetProgramInfoLog( mID, len, &len, &log[0] );
+ std::cerr << "Shader link error:\n"
+ << log << std::endl;
+ glDeleteProgram( mID );
+ mID = 0;
+ glDeleteShader( vert );
+ glDeleteShader( frag );
+ return false;
+ }
+
+ glDetachShader( mID, vert );
+ glDetachShader( mID, frag );
+ glDeleteShader( vert );
+ glDeleteShader( frag );
+
+ return true;
+}
+
+std::string Shader::readFile ( const std::string& path ) const {
+ std::ifstream in( path );
+ if( !in ) {
+ return std::string();
+ }
+ std::stringstream ss;
+ ss << in.rdbuf();
+ return ss.str();
+}
+
+} // namespace renderer