-
Notifications
You must be signed in to change notification settings - Fork 0
/
GLShader.cpp
103 lines (85 loc) · 2.16 KB
/
GLShader.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
#include <fstream>
#include <iostream>
#include "GLShader.h"
#include <glad/glad.h>
#include <GLFW/glfw3.h>
static void glClearError() {
while (glGetError() != GL_NO_ERROR);
}
static bool glCheckError(const char* func, const char* file, int line) {
while (GLenum err = glGetError()) {
std::cout << "[OpenGL ERROR] " << err
<< " : [" << file << "] [" << line << "] [" << func << "]"
<< '\n';
return false;
}
return true;
}
#define ASSERT(x) if(!(x)) __debugbreak();
#define GLCall(x) glClearError(); \
x; \
ASSERT(glCheckError(#x, __FILE__, __LINE__))
GLShader::GLShader()
{
id = glCreateProgram();
}
GLShader::~GLShader()
{
GLCall(glDeleteProgram(id));
}
GLShader& GLShader::Link()
{
GLCall(glLinkProgram(id));
GLCall(glValidateProgram(id));
return *this;
}
GLShader& GLShader::Attach(const std::string & filepath)
{
std::ifstream fd(filepath);
auto src = std::string(
std::istreambuf_iterator<char>(fd),
std::istreambuf_iterator<char>()
);
ASSERT(!src.empty())
const char* source = src.c_str();
unsigned int shader = CreateShader(filepath);
GLCall(glShaderSource(shader, 1, &source, nullptr));
GLCall(glCompileShader(shader));
int result = 1;
static char infoLog[1024];
GLCall(glGetShaderiv(shader, GL_COMPILE_STATUS, &result));
if (!result)
{
GLCall(glGetShaderInfoLog(shader, 1024, NULL, infoLog));
std::cout << "ERROR::SHADER_COMPILATION_ERROR: "
<< filepath << "\n"
<< infoLog << "\n ------------------------------------------------------- " << std::endl;
ASSERT(false);
}
GLCall(glAttachShader(id, shader));
//GLCall( glDetachShader(id, shader) );
GLCall(glDeleteShader(shader));
return *this;
}
void GLShader::Bind() const
{
GLCall(glUseProgram(id));
}
void GLShader::Unbind() const
{
GLCall(glUseProgram(0));
}
unsigned int GLShader::CreateShader(const std::string & filepath)
{
size_t index = filepath.rfind(".");
std::string ext = filepath.substr(index + 1);
unsigned int ShaderType;
if (ext == "vert") ShaderType = GL_VERTEX_SHADER;
else if (ext == "frag") ShaderType = GL_FRAGMENT_SHADER;
else {
ASSERT(false);
}
unsigned int shader = glCreateShader(ShaderType);
ASSERT(shader != 0);
return shader;
}