Botcraft 1.21.4
Loading...
Searching...
No Matches
Shader.cpp
Go to the documentation of this file.
3
4#include <fstream>
5
6namespace Botcraft
7{
8 namespace Renderer
9 {
10 Shader::Shader(const std::string& vertexPath, const std::string& fragmentPath)
11 {
12 // 1. retrieve the vertex/fragment source code from filePath
13 std::string vertexCode;
14 std::string fragmentCode;
15
16 if (!vertexPath.empty())
17 {
18 std::ifstream vShaderFile;
19 std::stringstream vShaderStream;
20 vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
21 try
22 {
23 vShaderFile.open(vertexPath);
24 vShaderStream << vShaderFile.rdbuf();
25 vShaderFile.close();
26 vertexCode = vShaderStream.str();
27 }
28 catch (std::ifstream::failure e)
29 {
30 LOG_ERROR("Vertex shader file not succesfully read");
31 }
32 }
33 else
34 {
35 vertexCode = default_vertex_shader;
36 }
37
38 if (!fragmentPath.empty())
39 {
40 std::ifstream fShaderFile;
41 fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
42 try
43 {
44 fShaderFile.open(fragmentPath);
45 std::stringstream fShaderStream;
46 fShaderStream << fShaderFile.rdbuf();
47 fShaderFile.close();
48 fragmentCode = fShaderStream.str();
49 }
50 catch (std::ifstream::failure e)
51 {
52 LOG_ERROR("Fragment shader file not sucesfully read");
53 }
54 }
55 else
56 {
57 fragmentCode = default_fragment_shader;
58 }
59
60 const char *vShaderCode = vertexCode.c_str();
61 const char *fShaderCode = fragmentCode.c_str();
62
63 // 2. compile shaders
64 unsigned int vertex, fragment;
65
66 // vertex shader
67 vertex = glCreateShader(GL_VERTEX_SHADER);
68 glShaderSource(vertex, 1, &vShaderCode, NULL);
69 glCompileShader(vertex);
70 CheckCompileErrors(vertex, "VERTEX");
71
72 // fragment Shader
73 fragment = glCreateShader(GL_FRAGMENT_SHADER);
74 glShaderSource(fragment, 1, &fShaderCode, NULL);
75 glCompileShader(fragment);
76 CheckCompileErrors(fragment, "FRAGMENT");
77
78 // shader Program
79 program = glCreateProgram();
80 glAttachShader(program, vertex);
81 glAttachShader(program, fragment);
82 glLinkProgram(program);
83 CheckCompileErrors(program, "PROGRAM");
84
85 // delete the shaders as they're linked into our program now and no longer necessary
86 glDeleteShader(vertex);
87 glDeleteShader(fragment);
88 }
89
91 {
92 glDeleteProgram(program);
93 }
94
95 const unsigned int Shader::Program()
96 {
97 return program;
98 }
99
100 // use/activate the shader
102 {
103 glUseProgram(program);
104 }
105
106 // utility uniform functions
107 void Shader::SetBool(const std::string& name, const bool value) const
108 {
109 unsigned int loc = glGetUniformLocation(program, name.c_str());
110 glUniform1i(loc, static_cast<int>(value));
111 }
112
113 void Shader::SetInt(const std::string& name, const int value) const
114 {
115 unsigned int loc = glGetUniformLocation(program, name.c_str());
116 glUniform1i(loc, value);
117 }
118
119 void Shader::SetFloat(const std::string& name, const float value) const
120 {
121 unsigned int loc = glGetUniformLocation(program, name.c_str());
122 glUniform1f(loc, value);
123 }
124
125 void Shader::SetMat4(const std::string& name, const glm::mat4& value) const
126 {
127 unsigned int loc = glGetUniformLocation(program, name.c_str());
128 glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(value));
129 }
130
131 void Shader::SetMat3(const std::string& name, const glm::mat3& value) const
132 {
133 unsigned int loc = glGetUniformLocation(program, name.c_str());
134 glUniformMatrix3fv(loc, 1, GL_FALSE, glm::value_ptr(value));
135 }
136
137 void Shader::SetMat4xN(const std::string & name, const std::vector<glm::mat4>& value) const
138 {
139 unsigned int loc = glGetUniformLocation(program, name.c_str());
140 glUniformMatrix4fv(loc, static_cast<int>(value.size()), GL_FALSE, glm::value_ptr(value[0]));
141 }
142
143 void Shader::SetMat3xN(const std::string& name, const std::vector<glm::mat3>& value) const
144 {
145 unsigned int loc = glGetUniformLocation(program, name.c_str());
146 glUniformMatrix3fv(loc, static_cast<int>(value.size()), GL_FALSE, glm::value_ptr(value[0]));
147 }
148
149 void Shader::SetVec3(const std::string& name, const glm::vec3& value) const
150 {
151 unsigned int loc = glGetUniformLocation(program, name.c_str());
152 glUniform3f(loc, value[0], value[1], value[2]);
153 }
154
155 void Shader::SetVec2(const std::string& name, const glm::vec2& value) const
156 {
157 unsigned int loc = glGetUniformLocation(program, name.c_str());
158 glUniform2f(loc, value[0], value[1]);
159 }
160
161 void Shader::CheckCompileErrors(const unsigned int shader, const std::string& type)
162 {
163 int success;
164 char infoLog[1024];
165 if (type != "PROGRAM")
166 {
167 glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
168 if (!success)
169 {
170 glGetShaderInfoLog(shader, 1024, NULL, infoLog);
171 LOG_ERROR("Shader compilation error of type: " << type << '\n' << infoLog);
172 }
173 }
174 else
175 {
176 glGetProgramiv(shader, GL_LINK_STATUS, &success);
177 if (!success)
178 {
179 glGetProgramInfoLog(shader, 1024, NULL, infoLog);
180 LOG_ERROR("Shader program linking error of type: " << type << '\n' << infoLog);
181 }
182 }
183 }
184
185 const std::string Shader::default_vertex_shader =
186 "#version 330 core\n"
187 "\n"
188 "layout (location = 0) in vec3 aPos;\n"
189 "//This matrix is actually four columns\n"
190 "layout (location = 1) in mat4 aModel;\n"
191 "//layout (location = 2) in vec4 aModelCol1;\n"
192 "//layout (location = 3) in vec4 aModelCol2;\n"
193 "//layout (location = 4) in vec4 aModelCol3;\n"
194 "layout (location = 5) in vec4 texture_coords;\n"
195 "layout (location = 6) in vec4 texture_coords_overlay;\n"
196 "layout (location = 7) in uint texture_data;\n"
197 "layout (location = 8) in uvec2 texture_multiplier;\n"
198 "\n"
199 "layout (std140) uniform MatriceView\n"
200 "{\n"
201 "\tmat4 view;\n"
202 "};\n"
203 "\n"
204 "uniform mat4 projection;\n"
205 "\n"
206 "out vec2 AtlasCoord;\n"
207 "out vec2 AtlasCoord_overlay;\n"
208 "flat out uint BackFaceDisplay;\n"
209 "flat out uint UseOverlay;\n"
210 "flat out vec4 TextureMultiplier;\n"
211 "flat out vec4 TextureMultiplier_overlay;\n"
212 "\n"
213 "void main()\n"
214 "{\n"
215 "\t//mat4 aModel;\n"
216 "\t//aModel[0] = aModelCol0;\n"
217 "\t//aModel[1] = aModelCol1;\n"
218 "\t//aModel[2] = aModelCol2;\n"
219 "\t//aModel[3] = aModelCol3;\n"
220 "\tgl_Position = projection * view * (aModel * vec4(aPos, 1.0));\n"
221 "\n"
222 "\tint vertex_id = gl_VertexID;\n"
223 "\n"
224 "\tint rotation = int(texture_data >> 3) & 0x03;\n"
225 "\n"
226 "\tint rotated_indices[4] = int[4](1, 3, 0, 2);\n"
227 "\tfor(int i = 0; i < rotation; ++i)\n"
228 "\t{\n"
229 "\t\tvertex_id = rotated_indices[vertex_id];\n"
230 "\t}\n"
231 "\n"
232 "\tAtlasCoord = vec2(texture_coords[2 * int(vertex_id % 2)], texture_coords[1 + 2 * int(vertex_id > 1)]);\n"
233 "\tAtlasCoord_overlay = vec2(texture_coords_overlay[2 * int(vertex_id % 2)], texture_coords_overlay[1 + 2 * int(vertex_id > 1)]);\n"
234 "\n"
235 "\tBackFaceDisplay = uint((texture_data >> 2) & uint(0x01));\n"
236 "\tUseOverlay = uint((texture_data >> 5) & uint(0x01));\n"
237 "\tTextureMultiplier = vec4(float(texture_multiplier[0] & uint(0xFF)), float((texture_multiplier[0] >> 8) & uint(0xFF)), float((texture_multiplier[0] >> 16) & uint(0xFF)), float((texture_multiplier[0] >> 24) & uint(0xFF))) / 255.0f;\n"
238 "\tTextureMultiplier_overlay = vec4(float(texture_multiplier[1] & uint(0xFF)), float((texture_multiplier[1] >> 8) & uint(0xFF)), float((texture_multiplier[1] >> 16) & uint(0xFF)), float((texture_multiplier[1] >> 24) & uint(0xFF))) / 255.0f;\n"
239 "}";
240
241 const std::string Shader::default_fragment_shader =
242 "#version 330 core\n"
243 "\n"
244 "in vec2 AtlasCoord;\n"
245 "in vec2 AtlasCoord_overlay;\n"
246 "flat in uint BackFaceDisplay;\n"
247 "flat in uint UseOverlay;\n"
248 "flat in vec4 TextureMultiplier;\n"
249 "flat in vec4 TextureMultiplier_overlay;\n"
250 "\n"
251 "uniform sampler2D atlas_texture;\n"
252 "\n"
253 "out vec4 FragColor;\n"
254 "\n"
255 "void main()\n"
256 "{\n"
257 "\tif(!bool(BackFaceDisplay) && !gl_FrontFacing)\n"
258 "\t{\n"
259 "\t\tdiscard;\n"
260 "\t}\n"
261 "\n"
262 "if(!bool(UseOverlay))\n"
263 "{\n"
264 "\tFragColor = TextureMultiplier * texture(atlas_texture, AtlasCoord);\n"
265 "}\n"
266 "else\n"
267 "{\n"
268 "\tvec4 base_color = TextureMultiplier * texture(atlas_texture, AtlasCoord);\n"
269 "\tvec4 overlay_color = TextureMultiplier_overlay * texture(atlas_texture, AtlasCoord_overlay);\n"
270 "\tfloat alpha = overlay_color[3] + base_color[3] * (1.0f - overlay_color[3]);\n"
271 "\tFragColor = vec4((vec3(overlay_color) * overlay_color[3] + (1.0f - overlay_color[3]) * vec3(base_color) * base_color[3]) / alpha, alpha);\n"
272 "}\n"
273 "\n"
274 "\tif(FragColor.a < 0.1)\n"
275 "\t{\n"
276 "\t\tdiscard;\n"
277 "\t}\n"
278 "}";
279 } // Renderer
280} // Botcraft
#define LOG_ERROR(osstream)
Definition Logger.hpp:45
void SetFloat(const std::string &name, const float value) const
Definition Shader.cpp:119
void SetMat3(const std::string &name, const glm::mat3 &value) const
Definition Shader.cpp:131
static const std::string default_fragment_shader
Definition Shader.hpp:42
void SetVec2(const std::string &name, const glm::vec2 &value) const
Definition Shader.cpp:155
void CheckCompileErrors(const unsigned int shader, const std::string &type)
Definition Shader.cpp:161
void SetVec3(const std::string &name, const glm::vec3 &value) const
Definition Shader.cpp:149
Shader(const std::string &vertexPath="", const std::string &fragmentPath="")
Definition Shader.cpp:10
void SetMat4xN(const std::string &name, const std::vector< glm::mat4 > &value) const
Definition Shader.cpp:137
const unsigned int Program()
Definition Shader.cpp:95
void SetMat4(const std::string &name, const glm::mat4 &value) const
Definition Shader.cpp:125
static const std::string default_vertex_shader
Definition Shader.hpp:41
void SetInt(const std::string &name, const int value) const
Definition Shader.cpp:113
void SetBool(const std::string &name, const bool value) const
Definition Shader.cpp:107
void SetMat3xN(const std::string &name, const std::vector< glm::mat3 > &value) const
Definition Shader.cpp:143