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;
}
};
|