diff --git a/OpenGL/cube/cube.a b/OpenGL/cube/cube.a index 0f82cd6..fd7ad2f 100755 Binary files a/OpenGL/cube/cube.a and b/OpenGL/cube/cube.a differ diff --git a/OpenGL/cube/src/main.cpp b/OpenGL/cube/src/main.cpp index 176c372..2fded2a 100644 --- a/OpenGL/cube/src/main.cpp +++ b/OpenGL/cube/src/main.cpp @@ -7,6 +7,8 @@ #include #include +#include "shader.hpp" + void GLAPIENTRY MessageCallback(GLenum source, GLenum type, GLuint id, @@ -27,71 +29,6 @@ public: bool isWindowClosed = true; }; -std::map VertexShaders; -std::map FragmentShaders; -std::map ShaderPrograms; - -std::string readShader(std::string source) { - std::ifstream t(source); - std::string shaderCode((std::istreambuf_iterator(t)), - std::istreambuf_iterator()); - // std::cout << shaderCode << std::endl; - return shaderCode; -} - -bool loadShader(std::string shaderSource, GLenum type, std::string shader) { - const char* source = shaderSource.c_str(); - - if (type == GL_VERTEX_SHADER) { - GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertexShader, 1, &source, NULL); - glCompileShader(vertexShader); - - GLint status; - glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status); - if (status == GL_FALSE) { - char buf[512]; - glGetShaderInfoLog(vertexShader, 512, NULL, buf); - std::cerr << buf << std::endl; - return false; - } - - VertexShaders[shader] = vertexShader; - std::cout << "Vertex shader at '" << shader << "' compiled..." << std::endl; - } else if (type == GL_FRAGMENT_SHADER) { - GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragmentShader, 1, &source, NULL); - glCompileShader(fragmentShader); - - GLint status; - glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status); - if (status == GL_FALSE) { - char buf[512]; - glGetShaderInfoLog(fragmentShader, 512, NULL, buf); - std::cerr << buf << std::endl; - return false; - } - - FragmentShaders[shader] = fragmentShader; - std::cout << "Fragment shader at '" << shader << "' compiled..." << std::endl; - } - return true; -} - -void makeShaderProgram(std::string vert, std::string frag, std::string program) { - GLuint shaderProgram = glCreateProgram(); - glAttachShader(shaderProgram, VertexShaders[vert]); - glAttachShader(shaderProgram, FragmentShaders[frag]); - ShaderPrograms[program] = shaderProgram; - std::cout << "Shader program '" << program << "' created" << std::endl; -} - -void applyShader(std::string shader) { - glLinkProgram(ShaderPrograms[shader]); - glUseProgram(ShaderPrograms[shader]); - std::cout << "Shader program '" << shader << "' applied" << std::endl; -} - int main(int argc, char** argv) { Game* game = new Game(); SDL_Init(SDL_INIT_EVERYTHING); @@ -152,24 +89,20 @@ int main(int argc, char** argv) { glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * numOfVerticies, vertices, GL_STATIC_DRAW); // Load, compile, apply and link shader programs - if (!loadShader(readShader("shaders/simple.vert"), GL_VERTEX_SHADER , "simpleVert") || - !loadShader(readShader("shaders/simple.frag"), GL_FRAGMENT_SHADER, "simpleFrag")) { - return 0; - } - makeShaderProgram("simpleVert", "simpleFrag", "simpleProc"); - applyShader("simpleProc"); + Shader simpleShader; + simpleShader.load("./shaders/simple").attatch().link().use(); - GLint posAttrib = glGetAttribLocation(ShaderPrograms["simpleProc"], "position"); + GLint posAttrib = glGetAttribLocation(simpleShader.getProgram(), "position"); glEnableVertexAttribArray(posAttrib); glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), 0); - GLint colAttrib = glGetAttribLocation(ShaderPrograms["simpleProc"], "colour"); + GLint colAttrib = glGetAttribLocation(simpleShader.getProgram(), "colour"); glEnableVertexAttribArray(colAttrib); glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void*)(2*sizeof(float))); - GLint triangleUniColour = glGetUniformLocation(ShaderPrograms["simpleProc"], "triangleColour"); + GLint triangleUniColour = glGetUniformLocation(simpleShader.getProgram(), "triangleColour"); glUniform3f(triangleUniColour, 0.2f, 0.8f, 0.3f); SDL_Event event; diff --git a/OpenGL/cube/src/shader.cpp b/OpenGL/cube/src/shader.cpp new file mode 100644 index 0000000..7b06a61 --- /dev/null +++ b/OpenGL/cube/src/shader.cpp @@ -0,0 +1,125 @@ +#include "shader.hpp" + +#include +#include + +Shader::Shader() { + m_program = glCreateProgram(); +} + +Shader& Shader::use() { + glUseProgram(m_program); + return *this; +} + +Shader& Shader::link() { + glLinkProgram(m_program); + return *this; +} + +Shader& Shader::attatch() { + glAttachShader(m_program, m_vert); + glAttachShader(m_program, m_frag); + return *this; +} + +std::string readShader(std::string source) { + std::ifstream t(source); + std::string shaderCode((std::istreambuf_iterator(t)), + std::istreambuf_iterator()); + return shaderCode; +} + +Shader& Shader::load(GLenum type, std::string sourceLoc) { + const char* source = readShader(sourceLoc).c_str(); + + if (type == GL_VERTEX_SHADER) { + GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertexShader, 1, &source, NULL); + glCompileShader(vertexShader); + + glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &m_status); + if (m_status == GL_FALSE) { + char buf[512]; + glGetShaderInfoLog(vertexShader, 512, NULL, buf); + std::cerr << buf << std::endl; + } + + m_vert = vertexShader; + m_vertLoc = sourceLoc; + m_vertSource = (std::string)source; + std::cout << "Vertex shader at '" << sourceLoc << "' compiled..." << std::endl; + } else if (type == GL_FRAGMENT_SHADER) { + GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragmentShader, 1, &source, NULL); + glCompileShader(fragmentShader); + + glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &m_status); + if (m_status == GL_FALSE) { + char buf[512]; + glGetShaderInfoLog(fragmentShader, 512, NULL, buf); + std::cerr << buf << std::endl; + } + + m_frag = fragmentShader; + m_fragLoc = sourceLoc; + m_fragSource = (std::string)source; + std::cout << "Fragment shader at '" << sourceLoc << "' compiled..." << std::endl; + } + return *this; +} + +Shader& Shader::load(std::string sourceLoc) { + m_vertLoc = sourceLoc + ".vert"; + m_fragLoc = sourceLoc + ".frag"; + + m_vertSource = readShader(m_vertLoc); + m_fragSource = readShader(m_fragLoc); + + m_vert = glCreateShader(GL_VERTEX_SHADER); + m_frag = glCreateShader(GL_FRAGMENT_SHADER); + + const char* vertSource = m_vertSource.c_str(); + glShaderSource(m_vert, 1, &vertSource, NULL); + glCompileShader(m_vert); + + const char* fragSource = m_fragSource.c_str(); + glShaderSource(m_frag, 1, &fragSource, NULL); + glCompileShader(m_frag); + + glGetShaderiv(m_vert, GL_COMPILE_STATUS, &m_status); + if (m_status == GL_FALSE) { + char buf[512]; + glGetShaderInfoLog(m_vert, 512, NULL, buf); + std::cerr << buf << std::endl; + } + + glGetShaderiv(m_frag, GL_COMPILE_STATUS, &m_status); + if (m_status == GL_FALSE) { + char buf[512]; + glGetShaderInfoLog(m_frag, 512, NULL, buf); + std::cerr << buf << std::endl; + } + + std::cout << "Vertex shader at '" << m_vertLoc << "' compiled..." << std::endl; + std::cout << "Fragment shader at '" << m_fragLoc << "' compiled..." << std::endl; + return *this; +} + +GLuint Shader::getProgram() { + return m_program; +} + +GLuint Shader::getVertex() { + return m_vert; +} + +GLuint Shader::getFragment() { + return m_frag; +} + +Shader::~Shader() { + glDeleteProgram(m_program); + glDeleteShader(m_vert); + glDeleteShader(m_frag); +} diff --git a/OpenGL/cube/src/shader.hpp b/OpenGL/cube/src/shader.hpp new file mode 100644 index 0000000..5db2c51 --- /dev/null +++ b/OpenGL/cube/src/shader.hpp @@ -0,0 +1,38 @@ +#ifndef _SHADER_H_ +#define _SHADER_H_ + +#include +#include + +class Shader { +public: + Shader(); + + Shader& use(); + Shader& link(); + Shader& attatch(); + Shader& load(GLenum type, std::string sourceLoc); + Shader& load(std::string sourceLoc); + + GLuint getProgram(); + GLuint getVertex(); + GLuint getFragment(); + + virtual ~Shader(); +private: + Shader(Shader const &) = delete; + Shader & operator=(Shader const &) = delete; + + GLuint m_program; + GLuint m_vert; + GLuint m_frag; + + std::string m_vertSource; + std::string m_fragSource; + std::string m_vertLoc; + std::string m_fragLoc; + + GLint m_status; +}; + +#endif