This repository has been archived by the owner on Mar 9, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
shader_utils.cpp
121 lines (102 loc) · 3.14 KB
/
shader_utils.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
#ifdef __APPLE__
/* Defined before OpenGL and GLUT includes to avoid deprecation messages */
#define GL_SILENCE_DEPRECATION
#include <GLFW/glfw3.h>
#endif
#include "logs.h"
#include "shader_utils.h"
#include <optional>
#include <iostream>
ShaderUtils::Program::Program() {}
ShaderUtils::Program::~Program()
{
if (vertexShader.has_value())
glDeleteShader(vertexShader.value());
if (vertexShader.has_value())
glDeleteShader(fragmentShader.value());
if (registered && program.has_value())
glDeleteProgram(program.value());
}
bool ShaderUtils::Program::registerShader(const ShaderUtils::Type shader_type, const char *shader_source)
{
int success = {};
char errorMessage[1024] = {};
bool isFragmentShader = shader_type == ShaderUtils::Type::FRAGMENT_SHADER_TYPE;
auto real_shader_type = !isFragmentShader ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER;
auto shader = glCreateShader(real_shader_type);
// Now, pass the shaders
glShaderSource(shader, 1, &shader_source, NULL);
// And now, compile them
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(shader, 1024, NULL, errorMessage);
if (isFragmentShader)
{
error("Fragment shader compilation error : " << errorMessage);
}
else
{
error("Vertex shader compilation error : " << errorMessage);
}
return false;
}
if (isFragmentShader)
{
fragmentShader = shader;
}
else
{
vertexShader = shader;
}
return true;
}
bool ShaderUtils::Program::registerProgram(bool erase_if_registered)
{
if (registered && (!erase_if_registered || !program.has_value()))
{
error("program is already registered");
return false;
}
if (registered && erase_if_registered)
{
glDeleteProgram(program.value());
registered = false;
}
if (!vertexShader.has_value() || !fragmentShader.has_value())
{
error("cannot compile program without vertex and fragment shaders");
return false;
}
int success = {};
char errorMessage[1024] = {};
const unsigned int vertexShaderValue = vertexShader.value();
const unsigned int fragmentShaderValue = fragmentShader.value();
program = glCreateProgram();
const unsigned int programValue = program.value();
glAttachShader(programValue, vertexShaderValue);
glAttachShader(programValue, fragmentShaderValue);
glLinkProgram(programValue);
glGetProgramiv(programValue, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(programValue, 1024, NULL, errorMessage);
error("Shader linking error: " << errorMessage);
return false;
}
// We can now delete our vertex and fragment shaders
glDeleteShader(vertexShaderValue);
glDeleteShader(fragmentShaderValue);
glUseProgram(programValue);
registered = true;
return true;
}
std::optional<unsigned int> ShaderUtils::Program::getProgram() const
{
return program;
}
bool ShaderUtils::Program::programIsRegistered() const
{
return registered;
}