diff --git a/Escape-the-Dawn/Escape-the-Dawn.vcxproj b/Escape-the-Dawn/Escape-the-Dawn.vcxproj index 65fac93..26d0e12 100644 --- a/Escape-the-Dawn/Escape-the-Dawn.vcxproj +++ b/Escape-the-Dawn/Escape-the-Dawn.vcxproj @@ -109,6 +109,7 @@ + diff --git a/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters b/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters index edf544f..e38c793 100644 --- a/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters +++ b/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters @@ -61,6 +61,7 @@ Components + diff --git a/Escape-the-Dawn/Renderer/Renderer.cpp b/Escape-the-Dawn/Renderer/Renderer.cpp index 62d014a..2821bb5 100644 --- a/Escape-the-Dawn/Renderer/Renderer.cpp +++ b/Escape-the-Dawn/Renderer/Renderer.cpp @@ -2,7 +2,7 @@ Renderer::Renderer() { - + glEnable(GL_DEPTH_TEST); } void Renderer::Draw() @@ -10,7 +10,7 @@ void Renderer::Draw() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(1.0f, 1.0f, 0.0f, 1.0f); - glUseProgram(shaderProgram); + m_ShaderProgram->Bind(); } void Renderer::DrawText() @@ -32,65 +32,7 @@ void Renderer::AddObjectToDraw() void Renderer::LoadContent() { - glEnable(GL_DEPTH_TEST); - LOG_INFO("Compiling Shader"); - - GLuint vertexShader = CompileShader(GL_VERTEX_SHADER, "Shaders/Vertex.glsl"); - GLuint fragmentShader = CompileShader(GL_FRAGMENT_SHADER, "Shaders\Fragment.glsl"); - - shaderProgram = glCreateProgram(); - glAttachShader(shaderProgram, vertexShader); - glAttachShader(shaderProgram, fragmentShader); - LOG_INFO("Linking shader program..."); - glLinkProgram(shaderProgram); - if(GLERROR("glLinkProgram")) - exit(EXIT_FAILURE); - + m_ShaderProgram->AddShader(std::unique_ptr(new VertexShader("Shaders/Vertex.glsl"))); + m_ShaderProgram->AddShader(std::unique_ptr(new FragmentShader("Shaders/Fragment.glsl"))); + m_ShaderProgram->Link(); } - -GLuint Renderer::CompileShader(GLenum shaderType, std::string fileName) -{ - std::string shaderFile; - std::ifstream in(fileName, std::ios::in); - - if(!in) - { - LOG_ERROR("Error: Failed to open shader file %s", fileName); - return 0; - } - in.seekg(0, std::ios::end); - shaderFile.resize((int)in.tellg()); - in.seekg(0, std::ios::beg); - in.read(&shaderFile[0], shaderFile.size()); - in.close(); - - GLuint shader = glCreateShader(shaderType); //GL_VERTEX_SHADER, GL_FRAGMENT_SHADER - if(GLERROR("glCreateShader")) - return 0; - - const GLchar* shaderFiles = shaderFile.c_str(); - const GLint length = shaderFile.length(); - glShaderSource(shader, 1, &shaderFiles, &length); - if(GLERROR("glShaderSource")) - return 0; - - glCompileShader(shader); - GLint compileStatus; - glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus); - if(compileStatus != GL_TRUE) - { - GLsizei infoLogLength; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength); - GLchar* infolog = new GLchar[infoLogLength]; - glGetShaderInfoLog(shader, infoLogLength, &infoLogLength, infolog); - std::cerr << infolog << std::endl; - delete[] infolog; - } - - if(GLERROR("glCompileShader")) - return 0; - - return shader; - -} - diff --git a/Escape-the-Dawn/Renderer/Renderer.h b/Escape-the-Dawn/Renderer/Renderer.h index a7224d2..77f37f5 100644 --- a/Escape-the-Dawn/Renderer/Renderer.h +++ b/Escape-the-Dawn/Renderer/Renderer.h @@ -16,12 +16,12 @@ #include #include "glerror.h" - +#include "ShaderProgram.h" class Renderer { public: - GLuint shaderProgram; + std::shared_ptr m_ShaderProgram; GLuint VAO; std::vector> Vertices; diff --git a/Escape-the-Dawn/ShaderProgram.h b/Escape-the-Dawn/ShaderProgram.h new file mode 100644 index 0000000..3d84820 --- /dev/null +++ b/Escape-the-Dawn/ShaderProgram.h @@ -0,0 +1,189 @@ +#ifndef ShaderProgram_h__ +#define ShaderProgram_h__ + +#include +#include +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include +#define GLFW_INCLUDE_GLU +#include +#include + +#include "glerror.h" + +class Shader +{ +public: + static GLuint CompileShader(GLenum shaderType, std::string fileName) + { + LOG_INFO("Compiling shader \"%s\"", fileName.c_str()); + + std::string shaderFile; + std::ifstream in(fileName, std::ios::in); + if(!in) + { + LOG_ERROR("Error: Failed to open shader file \"%s\"", fileName.c_str()); + return 0; + } + in.seekg(0, std::ios::end); + shaderFile.resize((int)in.tellg()); + in.seekg(0, std::ios::beg); + in.read(&shaderFile[0], shaderFile.size()); + in.close(); + + GLuint shader = glCreateShader(shaderType); + if(GLERROR("glCreateShader")) + return 0; + + const GLchar* shaderFiles = shaderFile.c_str(); + const GLint length = shaderFile.length(); + glShaderSource(shader, 1, &shaderFiles, &length); + if(GLERROR("glShaderSource")) + return 0; + + glCompileShader(shader); + + GLint compileStatus; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus); + if(compileStatus != GL_TRUE) + { + LOG_ERROR("Shader compilation failed"); + GLsizei infoLogLength; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength); + GLchar* infolog = new GLchar[infoLogLength]; + glGetShaderInfoLog(shader, infoLogLength, &infoLogLength, infolog); + LOG_ERROR(infolog); + delete[] infolog; + } + + if(GLERROR("glCompileShader")) + return 0; + + return shader; + } + + Shader(GLenum shaderType, std::string fileName) + : m_ShaderType(shaderType), m_FileName(fileName) + { + m_ShaderHandle = 0; + } + + virtual ~Shader() + { + glDeleteShader(m_ShaderHandle); + } + + GLuint Compile() + { + m_ShaderHandle = CompileShader(m_ShaderType, m_FileName); + return m_ShaderHandle; + } + + GLenum GetType() const { return m_ShaderType; } + std::string GetFileName() const { return m_FileName; } + GLuint GetHandle() const { return m_ShaderHandle; } + bool IsCompiled() const { return m_ShaderHandle != 0; } + +protected: + GLenum m_ShaderType; + std::string m_FileName; + GLint m_ShaderHandle; +}; + +template +class ShaderType : public Shader +{ +public: + ShaderType(std::string fileName) + : Shader(SHADERTYPE, fileName) { } +}; + +class VertexShader : public ShaderType +{ +public: + VertexShader(std::string fileName) + : ShaderType(fileName) { } +}; + +class FragmentShader : public ShaderType +{ +public: + FragmentShader(std::string fileName) + : ShaderType(fileName) { } +}; + +class GeometryShader : public ShaderType +{ +public: + GeometryShader(std::string fileName) + : ShaderType(fileName) { } +}; + +class ShaderProgram +{ +public: + ShaderProgram() + { + Initialize(); + } + + ShaderProgram(std::string vertexShaderFile, std::string fragmentShaderFile) + { + AddShader(std::unique_ptr(new VertexShader(vertexShaderFile))); + AddShader(std::unique_ptr(new VertexShader(fragmentShaderFile))); + Initialize(); + } + + void AddShader(std::unique_ptr shader) + { + if (!shader->IsCompiled()) { + shader->Compile(); + } + + m_Shaders.push_back(std::move(shader)); + } + + GLuint Link() + { + LOG_INFO("Linking shader program"); + m_ShaderProgramHandle = glCreateProgram(); + for (auto &shader : m_Shaders) { + glAttachShader(m_ShaderProgramHandle, shader->GetHandle()); + } + glLinkProgram(m_ShaderProgramHandle); + if (GLERROR("glLinkProgram")) + return 0; + + for (auto &shader : m_Shaders) { + shader.release(); + } + m_Shaders.clear(); + } + + void Bind() + { + if (m_ShaderProgramHandle == 0) + return; + + glActiveShaderProgram(0, m_ShaderProgramHandle); + } + + void Unbind() + { + glActiveShaderProgram(0, 0); + } + +private: + GLuint m_ShaderProgramHandle; + std::vector> m_Shaders; + + void Initialize() + { + m_ShaderProgramHandle = 0; + } +}; + +#endif // ShaderProgram_h__ \ No newline at end of file diff --git a/Escape-the-Dawn/Shaders/Fragment.glsl b/Escape-the-Dawn/Shaders/Fragment.glsl index e69de29..e71149a 100644 --- a/Escape-the-Dawn/Shaders/Fragment.glsl +++ b/Escape-the-Dawn/Shaders/Fragment.glsl @@ -0,0 +1,18 @@ +#version 440 + +uniform mat4 MVP; +uniform sampler2D texture0; + +in VertexData { + vec3 Position; + vec3 Color; + vec2 TextureCoord; +} Input; + +out vec4 FragmentColor; + +void main() +{ + vec4 texel = texture2D(texture0, Input.TextureCoord); + FragmentColor = texel * vec4(Input.Color, 0); +} \ No newline at end of file diff --git a/Escape-the-Dawn/Shaders/Vertex.glsl b/Escape-the-Dawn/Shaders/Vertex.glsl index e69de29..92b8723 100644 --- a/Escape-the-Dawn/Shaders/Vertex.glsl +++ b/Escape-the-Dawn/Shaders/Vertex.glsl @@ -0,0 +1,22 @@ +#version 440 + +uniform mat4 MVP; + +layout(location = 0) in vec3 Position; +layout(location = 1) in vec3 Normal; +layout(location = 2) in vec2 TextureCoord; + +out VertexData { + vec3 Position; + vec3 Normal; + vec2 TextureCoord; +} Output; + +void main() +{ + gl_Position = MVP * vec4(Position, 1.0); + + Output.Position = Position; + Output.Normal = Normal; + Output.TextureCoord = TextureCoord; +} \ No newline at end of file