summaryrefslogtreecommitdiff
path: root/engine-ocean/Graphics/shaderloader.h
blob: eeb8e8c83c776c4534f0d34b4c9f730d8c5db229 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#pragma once

#include "debug.h"

#include <vector>
#include <string>
#include <stdexcept>
#include <fstream>
#include <iostream>

class ShaderLoader{
public:
    static GLuint createShaderProgram(std::vector<GLenum> shaderTypes, std::vector<const char*> filepaths){
        // Create and compile shaders
        std::vector<GLuint> shaderIDs;
        for(int i = 0; i<shaderTypes.size(); i++){
            shaderIDs.push_back(createAndCompileShader(shaderTypes[i], filepaths[i]));
        }

        // Link the shader program
        GLuint programID = glCreateProgram();
        for(int i = 0; i<shaderIDs.size(); i++){
            glAttachShader(programID, shaderIDs[i]);
        }
        glLinkProgram(programID);

        // Print the info log if program fails to link
        GLint status;
        glGetProgramiv(programID, GL_LINK_STATUS, &status);
        if(status == GL_FALSE){
            GLint length;
            glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &length);
            std::string log(length, '\0');
            glGetProgramInfoLog(programID, length, nullptr, &log[0]);
            glDeleteProgram(programID);
            throw std::runtime_error(log);
        }

        // Individual shaders no longer necessary, stored in program
        for(int i = 0; i<shaderIDs.size(); i++){
            glDeleteShader(shaderIDs[i]);
        } 

        std::cout<<"END OF SHADERLOADER"<<std::endl;
        return programID;
    }

private:
    static std::string readFile(const char *filePath) {
        std::cout<<"READ FILE: "<<std::string(filePath)<<std::endl;
        std::string content;
        std::ifstream fileStream(filePath, std::ios::in);

        if(!fileStream.is_open()) {
            std::string log = "Could not read file "+std::string(filePath)+". File does not exist.";
            throw std::runtime_error(log);
            return "";
        }

        std::string line = "";
        while(std::getline(fileStream, line)) {
            content.append(line + "\n");
        }

        fileStream.close();

        return content;
    }

    static GLuint createAndCompileShader(GLenum shaderType, const char* filepath){
        std::cout<<"CREATE AND COMPILE SHADER: "<<shaderType<<std::endl;
        GLuint shaderID = glCreateShader(shaderType);

        // Read shader file
        std::string shaderStr = readFile(filepath);
        const char* shaderSrc = shaderStr.c_str();

        std::cout<<"GL SHADER SOURCE"<<std::endl;
        glShaderSource(shaderID, 1, &shaderSrc, NULL);

        std::cout<<"GL COMPILE SHADER: "<<shaderID<<std::endl;
        glCompileShader(shaderID);

        // Print info log if shader fails to compile
        GLint status;
        glGetShaderiv(shaderID, GL_COMPILE_STATUS, &status);
        if(status == GL_FALSE){
            GLint length;
            glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &length);
            std::string log(length, '\0');
            glGetShaderInfoLog(shaderID, length, nullptr, &log[0]);
            glDeleteShader(shaderID);
            throw std::runtime_error(log);
        }

        return shaderID;
    }
};