forked from michal1000w/GPUSmoke
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathShader.cpp
120 lines (94 loc) · 3.06 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
#include "Shader.h"
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
Shader::Shader(const std::string& filepath) : m_FilePath(filepath),
m_RendererID(0){
ShaderProgramSource source = ParseShader(filepath);
m_RendererID = CreateShader(source.VertexSource, source.FragmentSource);
}
Shader::~Shader() {
GLCall(glDeleteProgram(m_RendererID))
}
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() };
}
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);
int result;
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE) {
int length;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
char* message = (char*)alloca(length * sizeof(char));
glGetShaderInfoLog(id, length, &length, message);
std::cout << "Error Compiling Shader\n" << "Shader: " <<
(type == GL_VERTEX_SHADER ? "vertex" : "fragment") << std::endl;
std::cout << message << std::endl;
glDeleteShader(id);
return 0;
}
return id;
}
unsigned int Shader::CreateShader(const std::string& vertexShader,
const std::string& fragmentShader) {
std::cout << "Compiling Shaders...\n";
unsigned int program = glCreateProgram();
unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glValidateProgram(program);
glDeleteShader(vs);
glDeleteShader(fs);
std::cout << "Done\n";
return program;
}
void Shader::Bind() const {
GLCall(glUseProgram(m_RendererID))
}
void Shader::UnBind() const {
GLCall(glUseProgram(0))
}
int Shader::GetUniformLocation(const std::string& name) {
if (m_UniformLocationCache.find(name) != m_UniformLocationCache.end())
return m_UniformLocationCache[name];
GLCall(int location = glGetUniformLocation(m_RendererID, name.c_str()))
if (location == -1)
std::cout << "Warning!\nUniform " << name << " doesn't exist\n";
m_UniformLocationCache[name] = location;
return location;
}
void Shader::SetUniform4f(const std::string& name, float v0, float v1, float v2, float v3) {
GLCall(glUniform4f(GetUniformLocation(name), v0, v1, v2, v3))
}
void Shader::SetUniform1f(const std::string& name, float value) {
GLCall(glUniform1f(GetUniformLocation(name), value))
}
void Shader::SetUniform1i(const std::string& name, int value) {
GLCall(glUniform1i(GetUniformLocation(name), value))
}