From 8a48c28fb5660b39b2de3d2a932e64c6fc04e17a Mon Sep 17 00:00:00 2001 From: Daniel Brunner <0xFEEDC0DE64@gmail.com> Date: Wed, 16 Aug 2017 21:43:48 +0200 Subject: [PATCH] Added Shader --- FluckyGameOpenGL.pro | 9 +++- main.cpp | 10 +++-- res/basicShader.frag | 6 +++ res/basicShader.vert | 8 ++++ shader.cpp | 103 +++++++++++++++++++++++++++++++++++++++++++ shader.h | 30 +++++++++++++ 6 files changed, 161 insertions(+), 5 deletions(-) create mode 100644 res/basicShader.frag create mode 100644 res/basicShader.vert create mode 100644 shader.cpp create mode 100644 shader.h diff --git a/FluckyGameOpenGL.pro b/FluckyGameOpenGL.pro index f2b7249..b20106a 100644 --- a/FluckyGameOpenGL.pro +++ b/FluckyGameOpenGL.pro @@ -3,8 +3,13 @@ TEMPLATE = app CONFIG -= qt DEFINES -= UNICODE QT_LARGEFILE_SUPPORT -HEADERS += +HEADERS += \ + shader.h -SOURCES += main.cpp +SOURCES += main.cpp \ + shader.cpp LIBS += -lstdc++ -lGL -lGLEW -lSDL2 + +DISTFILES += res/basicShader.frag \ + res/basicShader.vert diff --git a/main.cpp b/main.cpp index 19b7f01..3b3366c 100644 --- a/main.cpp +++ b/main.cpp @@ -5,9 +5,11 @@ #include #include -const int width = 800; -const int height = 600; -const std::string title = "Flucky Game"; +#include "shader.h" + +static const int width = 800; +static const int height = 600; +static const std::string title = "Flucky Game"; int main() { @@ -24,6 +26,8 @@ int main() return 1; } + Shader shader("../FluckyGameOpenGL/res/basicShader"); + while(true) { glClearColor(.5f, .5f, 1.f, 1.0f); diff --git a/res/basicShader.frag b/res/basicShader.frag new file mode 100644 index 0000000..2aa3ef7 --- /dev/null +++ b/res/basicShader.frag @@ -0,0 +1,6 @@ +#version 120 + +void main() +{ + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); +} diff --git a/res/basicShader.vert b/res/basicShader.vert new file mode 100644 index 0000000..316fb42 --- /dev/null +++ b/res/basicShader.vert @@ -0,0 +1,8 @@ +#version 120 + +attribute vec3 position; + +void main() +{ + gl_Position = vec4(position, 1.0); +} diff --git a/shader.cpp b/shader.cpp new file mode 100644 index 0000000..1d510e9 --- /dev/null +++ b/shader.cpp @@ -0,0 +1,103 @@ +#include "shader.h" + +#include +#include + +Shader::Shader(const std::string &fileName) +{ + m_program = glCreateProgram(); + m_shaders[0] = createShader(loadShader(fileName + ".vert"), GL_VERTEX_SHADER); + m_shaders[1] = createShader(loadShader(fileName + ".frag"), GL_FRAGMENT_SHADER); + + for(unsigned int i = 0; i < NUM_SHADERS; i++) + glAttachShader(m_program, m_shaders[i]); + + //glBindAttribLocation(m_program, 0, "position"); + + glLinkProgram(m_program); + checkShaderError(m_program, GL_LINK_STATUS, true, "Error: Program linking failed: "); + + glValidateProgram(m_program); + checkShaderError(m_program, GL_VALIDATE_STATUS, true, "Error: Program is invalid: "); +} + +Shader::~Shader() +{ + for(unsigned int i = 0; i < NUM_SHADERS; i++) + { + glDetachShader(m_program, m_shaders[i]); + glDeleteShader(m_shaders[i]); + } + + glDeleteProgram(m_program); +} + +void Shader::bind() +{ + glUseProgram(m_program); +} + +std::string Shader::loadShader(const std::string &fileName) +{ + std::ifstream file; + file.open(fileName); + + std::string output; + std::string line; + + if(file.is_open()) + { + while(file.good()) + { + getline(file, line); + output.append(line + "\n"); + } + } + else + { + std::cerr << "Unable to load shader: " << fileName << std::endl; + } + + return output; +} + +void Shader::checkShaderError(GLuint shader, GLuint flag, bool isProgram, const std::string &errorMessage) +{ + GLint success = 0; + GLchar error[1024] = { 0 }; + + if(isProgram) + glGetProgramiv(shader, flag, &success); + else + glGetShaderiv(shader, flag, &success); + + if(success == GL_FALSE) + { + if(isProgram) + glGetProgramInfoLog(shader, sizeof(error), NULL, error); + else + glGetShaderInfoLog(shader, sizeof(error), NULL, error); + + std::cerr << errorMessage << ": '" << error << "'" << std::endl; + } +} + +GLuint Shader::createShader(const std::string &text, GLenum shaderType) +{ + GLuint shader = glCreateShader(shaderType); + + if(shader == 0) + std::cerr << "Error: Shader creation failed!" << std::endl; + + const GLchar* shaderSourceStrings[1]; + GLint shaderSourceStringLengths[1]; + + shaderSourceStrings[0] = text.c_str(); + shaderSourceStringLengths[0] = text.length(); + + glShaderSource(shader, 1, shaderSourceStrings, shaderSourceStringLengths); + glCompileShader(shader); + checkShaderError(shader, GL_COMPILE_STATUS, true, "Error: Shader compilation failed: "); + + return shader; +} diff --git a/shader.h b/shader.h new file mode 100644 index 0000000..fa093fa --- /dev/null +++ b/shader.h @@ -0,0 +1,30 @@ +#ifndef SHADER_H +#define SHADER_H + +#include +#include + +class Shader +{ +public: + explicit Shader(const std::string &fileName); + virtual ~Shader(); + + void bind(); + +private: + //disable copy + Shader(const Shader &) = delete; + Shader &operator=(const Shader &) = delete; + + static std::string loadShader(const std::string& fileName); + static void checkShaderError(GLuint shader, GLuint flag, bool isProgram, const std::string& errorMessage); + static GLuint createShader(const std::string &text, GLenum shaderType); + + static constexpr unsigned int NUM_SHADERS = 2; + + GLuint m_program; + GLuint m_shaders[NUM_SHADERS]; +}; + +#endif // SHADER_H