-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshader.cpp
124 lines (104 loc) · 2.94 KB
/
shader.cpp
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "shader.h"
Shader::Shader(const char* vertexLocation, const char* fragmentLocation)
{
ID = 0;
// Read shader source code from files
std::string vertexShaderSource = readFile(vertexLocation);
std::string fragmentShaderSource = readFile(fragmentLocation);
compileShader(vertexShaderSource.c_str(), fragmentShaderSource.c_str());
}
Shader::~Shader()
{
clear();
}
// Function to read the content of a file into a string
std::string Shader::readFile(std::string filename)
{
std::fstream file(filename, std::ios::in);
if(!file.is_open())
{
std::cerr << "Failed to open file " << filename << std::endl;
return "";
}
std::stringstream buffer;
buffer << file.rdbuf();
file.close();
return buffer.str();
}
void Shader::addShader(GLuint program, const char* shaderCode, GLenum shaderType)
{
GLuint shader = glCreateShader(shaderType);
const GLchar* src = shaderCode;
GLint length = strlen(shaderCode);
glShaderSource(shader, 1, &src, &length);
glCompileShader(shader);
GLint success = 0;
GLchar error[1024] = { 0 };
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if(!success)
{
std::cerr << "Failed to compile shader" << std::endl;
glGetShaderInfoLog(shader, sizeof(error), nullptr, error);
std::cerr << "Error:\n" << error << std::endl;
return;
}
glAttachShader(program, shader);
glDeleteShader(shader);
}
void Shader::compileShader(const char* vertexCode, const char* fragmentCode)
{
// Create shader program
ID = glCreateProgram();
if(!ID)
{
std::cerr << "Failed to create shader program" << std::endl;
return;
}
addShader(ID, vertexCode, GL_VERTEX_SHADER);
addShader(ID, fragmentCode, GL_FRAGMENT_SHADER);
// Link the program
glLinkProgram(ID);
GLint success;
glGetProgramiv(ID, GL_LINK_STATUS, &success);
if(!success)
{
char error[1024];
glGetProgramInfoLog(ID, sizeof(error), nullptr, error);
std::cerr << "Program linking error:\n" << error << std::endl;
return;
}
// Validate the program
glValidateProgram(ID);
glGetProgramiv(ID, GL_VALIDATE_STATUS, &success);
if(!success)
{
char error[1024];
glGetProgramInfoLog(ID, sizeof(error), nullptr, error);
std::cerr << "Program validation error:\n" << error << std::endl;
return;
}
}
void Shader::use()
{
glUseProgram(ID);
}
void Shader::clear()
{
if(ID != 0)
{
glDeleteProgram(ID);
ID = 0;
}
}
void Shader::setBool(const std::string &name, bool value) const
{
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
}
void Shader::setInt(const std::string &name, int value) const
{
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
}
void Shader::setFloat(const std::string &name, float value) const
{
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
}