-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathshader.cpp
158 lines (119 loc) · 3.56 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include "shader.h"
Shader::Shader(const std::string& filepath) : m_FilePath(filepath)
{
ShaderProgramSource source = ParseShader(filepath);
std::cout << source.VertexSource << source.FragmentSource << std::endl;
m_Renderer_ID = CreateShader(source.VertexSource, source.FragmentSource);
}
Shader::~Shader()
{
glDeleteProgram(m_Renderer_ID);
}
void Shader::Bind()
{
glUseProgram(m_Renderer_ID);
}
void Shader::Unbind()
{
glUseProgram(0);
}
GLint Shader::getAttribLocation(const char* name)
{
if (m_AttribLocationCache.find(name) != m_AttribLocationCache.end())
return m_AttribLocationCache[name];
GLint location = glGetAttribLocation(m_Renderer_ID, name);
if (-1 == location) {
std::cout << "WARNING: AttribLocation " << name << " do not exist" << std::endl;
}
m_UniformLocationCache[name] = location;
return glGetAttribLocation(m_Renderer_ID, name);
}
GLint Shader::GetUniformLocation(const char* name)
{
if (m_UniformLocationCache.find(name) != m_UniformLocationCache.end())
return m_UniformLocationCache[name];
GLint location = glGetUniformLocation(m_Renderer_ID, name);
if (-1 == location) {
std::cout << "WARNING: Uniform " << name << " do not exist" << std::endl;
}
m_UniformLocationCache[name] = location;
return location;
}
void Shader::setUniform1f(const char* name, float v0)
{
glUniform1f(GetUniformLocation(name), v0);
}
void Shader::setUniform4fv(const char* name, glm::mat4 matrix)
{
glUniformMatrix4fv(GetUniformLocation(name), 1, GL_FALSE, glm::value_ptr(matrix));
}
void Shader::setUniform3fv(const char* name, glm::vec3 vector3f)
{
glUniform3fv(GetUniformLocation(name), 1, glm::value_ptr(vector3f));
}
void Shader::setUniform1i(const char* name, int i0)
{
glUniform1i(GetUniformLocation(name), i0);
}
unsigned int Shader::CompileShader(unsigned int type, const std::string& source)
{
unsigned int id = glCreateShader(type);
const char* src = source.c_str();
glShaderSource(id, 1, &src, nullptr);
glCompileShader(id);
// this below code is to see if the shader compiled properly
int result;
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
if (GL_FALSE == result)
{
int length;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
char* message = new char[length * sizeof(char)];
glGetShaderInfoLog(id, length, &length, message);
std::cout << "failed to compile : " << (type == GL_VERTEX_SHADER ? "Vertex Shader" : "fragment shader") << std::endl;
std::cout << message << std::endl;
delete[]message;
return 0;
}
//////
return id;
}
unsigned int Shader::CreateShader(const std::string& vertexshader, const std::string& fragmentshader)
{
unsigned int program = glCreateProgram();
unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexshader); //vertex shader
unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentshader); // fragment shader
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glValidateProgram(program);
glDeleteShader(vs);
glDeleteShader(fs);
return program;
}
ShaderProgramSource Shader::ParseShader(const std::string& filepath)
{
std::ifstream stream(filepath);
enum class ShaderType
{
NONE = -1, VERTEX = 0, FRAGMENT = 1
};
std::string line;
std::stringstream ss[2];
ShaderType type = ShaderType::NONE;
while (getline(stream, line))
{
if (line.find("#shader") != std::string::npos)
{
if (line.find("vertex") != std::string::npos)
type = ShaderType::VERTEX;
else if (line.find("fragment") != std::string::npos)
type = ShaderType::FRAGMENT;
}
else
{
ss[(int)type] << line << '\n';
}
}
return { ss[0].str(),ss[1].str() };
}