Kajetan Johannes Hammerle 3 年 前
コミット
647e4f95de
4 ファイル変更130 行追加2 行削除
  1. 2 1
      meson.build
  2. 0 1
      utils/Array.h
  3. 92 0
      wrapper/Shader.cpp
  4. 36 0
      wrapper/Shader.h

+ 2 - 1
meson.build

@@ -33,7 +33,8 @@ sources = ['Main.cpp',
     'wrapper/Texture.cpp',
     'wrapper/GL.cpp',
     'wrapper/GLFW.cpp',
-    'wrapper/GLEW.cpp', ]
+    'wrapper/GLEW.cpp', 
+    'wrapper/Shader.cpp']
 
 glewDep = dependency('glew')
 glfwDep = dependency('glfw3')

+ 0 - 1
utils/Array.h

@@ -1,7 +1,6 @@
 #ifndef ARRAY_H
 #define ARRAY_H
 
-#include <array>
 #include "utils/StringBuffer.h"
 
 template<typename T, int N>

+ 92 - 0
wrapper/Shader.cpp

@@ -0,0 +1,92 @@
+#include <fstream>
+#include <iostream>
+
+#include "wrapper/Shader.h"
+#include "wrapper/GL.h"
+
+Shader::Shader(const char* vertexPath, const char* fragmentPath) : vertexShader(0), fragmentShader(0), program(0) {
+    if(readFileAndCompile(vertexPath, vertexShader, GL_VERTEX_SHADER) || 
+            readFileAndCompile(fragmentPath, fragmentShader, GL_FRAGMENT_SHADER)) {
+        return;
+    }
+    program = glCreateProgram();
+    glAttachShader(program, vertexShader);
+    glAttachShader(program, fragmentShader);
+    glLinkProgram(program);
+    if(GL::checkAndPrintError("cannot link")) {
+        return;
+    }
+    GLint linked;
+    glGetProgramiv(program, GL_LINK_STATUS, &linked);
+    if(!linked) {
+        ErrorLog log;
+        glGetProgramInfoLog(program, log.getLength(), nullptr, log.begin());
+        std::cout << "linker log: " << log.begin() << "\n";
+        return;
+    }
+}
+
+Shader::~Shader() {
+    glDeleteShader(vertexShader);
+    glDeleteShader(fragmentShader);
+    glDeleteProgram(program);
+}
+
+bool Shader::readFileAndCompile(const char* path, GLuint& shader, GLenum shaderType) {
+    std::cout << "shader: " << path << '\n';
+    Code code;
+    if(readFile(code, path)) {
+        return true;
+    }
+    return compile(shader, code, shaderType);
+}
+
+bool Shader::readFile(Code& code, const char* path) const {
+    std::ifstream in;
+    in.open(path);
+    if(!in.good()) {
+        std::cout << "cannot read file\n";
+        return true;
+    }
+    in.get(code.begin(), code.getLength(), EOF);
+    return false;
+}
+
+bool Shader::hasError() const {
+    return vertexShader == 0 || fragmentShader == 0 || program == 0;
+}
+
+bool Shader::compile(GLuint& shader, const Code& code, GLenum shaderType) {
+    shader = glCreateShader(shaderType);
+    const GLchar* buffer = code.begin();
+    glShaderSource(shader, 1, &buffer, nullptr);
+    glCompileShader(shader);
+    if(GL::checkAndPrintError("compile error")) {
+        return true;
+    }
+    GLint compiled;
+    glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+    if(!compiled) {
+        ErrorLog log;
+        glGetShaderInfoLog(shader, log.getLength(), nullptr, log.begin());
+        std::cout << "compiler log: " << log.begin() << "\n";
+        return true;
+    }
+    return false;
+}
+
+void Shader::use() const {
+    glUseProgram(program);
+}
+
+void Shader::setMatrix(const GLchar* name, const GLfloat* data) {
+    glUniformMatrix4fv(glGetUniformLocation(program, name), 1, GL_TRUE, data);
+}
+
+void Shader::setInt(const GLchar* name, GLint data) {
+    glUniform1i(glGetUniformLocation(program, name), data);
+}
+
+void Shader::setFloat(const GLchar* name, GLfloat data) {
+    glUniform1f(glGetUniformLocation(program, name), data);
+}

+ 36 - 0
wrapper/Shader.h

@@ -0,0 +1,36 @@
+#ifndef SHADER_H
+#define SHADER_H
+
+#include <GL/glew.h>
+
+#include "utils/Array.h"
+
+class Shader final {
+    GLuint vertexShader;
+    GLuint fragmentShader;
+    GLuint program;
+    
+public:
+    Shader(const char* vertexPath, const char* fragmentPath);
+    ~Shader();
+    Shader(const Shader& other) = delete;
+    Shader(Shader&& other) = delete;
+    Shader& operator=(const Shader& other) = delete;
+    Shader& operator=(Shader&& other) = delete;
+
+    bool hasError() const;
+    
+    void use() const;
+    void setMatrix(const GLchar* name, const GLfloat* data);
+    void setInt(const GLchar* name, GLint data);
+    void setFloat(const GLchar* name, GLfloat data);
+
+private:
+    typedef Array<GLchar, 1024 * 128> Code;
+    typedef Array<GLchar, 1024> ErrorLog;
+    bool readFileAndCompile(const char* path, GLuint& shader, GLenum shaderType);
+    bool readFile(Code& code, const char* path) const;
+    bool compile(GLuint& shader, const Code& code, GLenum shaderType);
+};
+
+#endif