Easy3D 2.5.3
shader_program.h
1/********************************************************************
2 * Copyright (C) 2015 Liangliang Nan <liangliang.nan@gmail.com>
3 * https://3d.bk.tudelft.nl/liangliang/
4 *
5 * This file is part of Easy3D. If it is useful in your research/work,
6 * I would be grateful if you show your appreciation by citing it:
7 * ------------------------------------------------------------------
8 * Liangliang Nan.
9 * Easy3D: a lightweight, easy-to-use, and efficient C++ library
10 * for processing and rendering 3D data.
11 * Journal of Open Source Software, 6(64), 3255, 2021.
12 * ------------------------------------------------------------------
13 *
14 * Easy3D is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License Version 3
16 * as published by the Free Software Foundation.
17 *
18 * Easy3D is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 ********************************************************************/
26
41#ifndef EASY3D_RENDERER_SHADER_PROGRAM_H
42#define EASY3D_RENDERER_SHADER_PROGRAM_H
43
44#include <unordered_map>
45#include <vector>
46#include <string>
47
48
49namespace easy3d {
50
51
78 {
79 public:
80
81 // Types of Vertex Attributes
82 enum AttribType {
83 POSITION,
84 COLOR,
85 NORMAL,
86 TEXCOORD
87 };
88 typedef std::pair<ShaderProgram::AttribType, std::string> Attribute;
89
90 // Types of Shaders
91 enum ShaderType {
92 VERTEX,
93 FRAGMENT,
94 GEOMETRY,
95 TESS_CONTROL,
96 TESS_EVALUATION,
97 COMPUTE,
98 NUM_SHADER_TYPES
99 };
100
101 static bool is_supported();
102
108 explicit ShaderProgram(const std::string& name = "unknown");
110
111 void set_name(const std::string& name) { name_ = name; }
112 const std::string& name() const { return name_; }
113
115 void set_verbose(bool v) { verbose_ = v; }
116
117 // ---------------------------------------------------------------
118
120 unsigned int get_program() const;
121
123 void clear();
124
125 //---------------------- Creation ---------------------------
126
133 bool load_shader_from_file(ShaderType st, const std::string& file_name, const std::string& inc_id = "#include");
134
140 bool load_shader_from_code(ShaderType st, const std::string& code);
141
150 void set_attrib_name(ShaderProgram::AttribType at, const std::string& name) const;
151 void set_attrib_names(const std::vector<ShaderProgram::Attribute>& attributes) const;
152
156 bool link_program();
157
165 void set_program_output(int index, const std::string& name) const;
166
174 int program_output(const std::string& name) const;
175
176 //---------------------- Rendering ---------------------------
177
179 void bind() const;
180
181 // generic function to set the uniform <name> to value
182 // NOTE: if your uniform is an array type, be careful to use the correct uniform names. For example, you have
183 // 'uniform vec2/float values[8]' in your shader code, the uniform name is 'values[0]' (not 'values').
184 // So calling to this function looks like: program->set_uniform("values[0]", valueArray);
185 ShaderProgram* set_uniform(const std::string& name, const void *value);
186
187 // For int and bool uniforms. Sets the uniform <name> to the int value
188 ShaderProgram* set_uniform(const std::string& name, int value);
189
190 // For unsigned int uniforms. Sets the uniform <name> to the unsigned int value
191 ShaderProgram* set_uniform(const std::string& name, unsigned int value);
192
193 // For float uniforms. Sets the uniform <name> to the float value
194 ShaderProgram* set_uniform(const std::string& name, float value);
195
199 ShaderProgram* set_block(const std::string& name, const void *value);
200
212 ShaderProgram* set_block_uniform(const std::string& blockName, const std::string& uniformName, const void *value);
213
217 ShaderProgram* set_block_uniform_array_element(const std::string& blockName, const std::string& uniformName, int arrayIndex, const void* value);
218
219 // tex_target: GL_TEXTURE_2D, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_ARRAY
220 // default value is GL_TEXTURE_2D (0x0DE1, just to eliminate the inclusion of gl header file).
221 ShaderProgram* bind_texture(const std::string& name, unsigned int tex_id, int unit, unsigned int tex_target = 0x0DE1);
222 ShaderProgram* release_texture(unsigned int tex_target = 0x0DE1);
223
225 void release() const;
226
227 // ---------------------- Other info -------------------------------
228
229 int get_attribute_location(const std::string& name) const;
230
231 // methods to inquire as to what uniforms/attributes are used by this shader. This can
232 // save some compute time if the uniforms or attributes are expensive to compute.
233 // Note: the program must be compiled and linked.
234 bool is_uniform_used(const std::string& name);
235 bool is_attribute_used(const std::string& name);
236
237 // returns GL_VALIDATE_STATUS for the program
238 // glValidateProgram() is meant to be called directly before a draw call (i.e., glDraw*())
239 // with that shader bound and all the bindings (VAO, textures) set. Its purpose is to ensure
240 // that the shader can execute given the current GL state.
241 bool is_program_valid() const;
242
244 bool is_program_linked() const;
245
247 bool is_bound() const;
248
249 // return true if shader compilation was successfully, false otherwise.
250 // 'log' returns the shader's infolog
251 bool shader_info_log(std::string& log, unsigned int shader) const;
252
253 // return true if program linkage was successfully, false otherwise.
254 // 'log' returns the program's infolog
255 bool program_info_log(std::string& log) const;
256
257 // useful for debug. More detailed version are implemented in OpenglInfo class.
258 // NOTE: require OpenGL >= 4.3
259 void print_active_attributes();
260 void print_active_uniforms();
261 void print_active_uniform_blocks();
262
263 // ---------------------- Load/Save binary -------------------------------
264 // The ready-to-use (i.e., compiled and linked) program in a single binary file.
265 // NOTE: require OpenGL >= 4.1
266 bool load_binary(const std::string& file_name);
267 bool save_binary(const std::string& file_name);
268
274 // aux function to read the shader's source code from a file
275 static std::string load_shader_source(const std::string& file_name, const std::string& inc_id = "#include");
276
277 protected:
278
279 // AUX STRUCTURES
280
281 // stores information for uniforms
282 struct Uniform {
283 std::string name;
284 unsigned int type;
285 int location;
286 int size;
287 unsigned int stride;
288 };
289
290 // stores information for block uniforms
291 struct BlockUniform {
292 std::string name;
293 unsigned int type;
294 unsigned int offset;
295 unsigned int size;
296 unsigned int arrayStride;
297 };
298
299 // Uniform blocks are a very convenient feature for two reasons :
300 // (1) Allow uniform sharing between programs �C set once, use many times
301 // (2) Allow setting multiple values at once
302 struct UniformBlock { // stores information for a block and its uniforms
303 std::string name;
304 // size of the uniform block
305 int size;
306 // buffer bound to the index point
307 unsigned int buffer;
308 // binding index
309 unsigned int bindingIndex;
310 // uniforms information
311 // maps of std::string can be super slow when calling find with a string literal or const char*
312 // as find forces construction/copy/destruction of a std::sting copy of the const char*.
313 std::unordered_map<std::string, BlockUniform> uniformOffsets;
314 };
315
316 // VARIABLES
317
318 // blockCount is used to assign binding indexes
319 static int spBlockCount;
320
321 // Stores info on all blocks found
322 // maps of std::string can be super slow when calling find with a string literal or const char*
323 // as find forces construction/copy/destruction of a std::sting copy of the const char*.
324 static std::unordered_map<std::string, UniformBlock> spBlocks;
325
326 // stores the OpenGL shader types
327 static unsigned int spGLShaderTypes[ShaderProgram::NUM_SHADER_TYPES];
328
329 // stores the text string related to each type
330 static std::string spStringShaderTypes[ShaderProgram::NUM_SHADER_TYPES];
331
332 // the program handle
333 unsigned int program_;
334
335 // stores info on the uniforms
336 // maps of std::string can be super slow when calling find with a string literal or const char*
337 // as find forces construction/copy/destruction of a std::sting copy of the const char*.
338 std::unordered_map<std::string, Uniform> pUniforms;
339
340 // AUX FUNCTIONS
341
342 // aux function to get info on the uniforms referenced by the shaders
343 void _add_uniforms();
344
345 // aux function to store the info of a uniform
346 void _add_uniform(const std::string& name, unsigned int type, unsigned int size);
347
348 // aux function to get info on the blocks referenced by the shaders
349 void _add_blocks();
350
351 // aux function to determine the size in bytes based on the OpenGL type
352 int _type_size(unsigned int type) const;
353
354 std::string _type_string(unsigned int type) const;
355
356 // aux function to read a previously compiled and linked program code from a file
357 std::string _read_linked_program(const std::string& file);
358
359 private:
360 std::string name_;
361 bool verbose_; // log any issues found
362
363 //copying disabled
365 ShaderProgram& operator=(const ShaderProgram&);
366
367 private:
368 friend class ShaderManager;
369 };
370
371}
372
373
374#endif // EASY3D_RENDERER_SHADER_PROGRAM_H
OpenGL Shader Compilation.
Definition: shader_program.h:78
bool program_info_log(std::string &log) const
returns a string with the program's infolog
Definition: shader_program.cpp:294
bool load_shader_from_file(ShaderType st, const std::string &file_name, const std::string &inc_id="#include")
Definition: shader_program.cpp:199
bool load_shader_from_code(ShaderType st, const std::string &code)
Definition: shader_program.cpp:209
void bind() const
Starts using the program.
Definition: shader_program.cpp:678
unsigned int get_program() const
Returns the program index.
Definition: shader_program.cpp:337
void set_program_output(int index, const std::string &name) const
Definition: shader_program.cpp:311
void set_attrib_name(ShaderProgram::AttribType at, const std::string &name) const
Definition: shader_program.cpp:321
bool is_program_linked() const
Returns true if program linked, false otherwise.
Definition: shader_program.cpp:669
void release() const
Ends using the program.
Definition: shader_program.cpp:689
bool shader_info_log(std::string &log, unsigned int shader) const
returns a string with a shader's infolog
Definition: shader_program.cpp:276
bool link_program()
Definition: shader_program.cpp:247
ShaderProgram(const std::string &name="unknown")
Definition: shader_program.cpp:91
void set_verbose(bool v)
Sets true to log any issues found.
Definition: shader_program.h:115
ShaderProgram * set_block(const std::string &name, const void *value)
Definition: shader_program.cpp:342
static std::string load_shader_source(const std::string &file_name, const std::string &inc_id="#include")
Definition: shader_program.cpp:124
ShaderProgram * set_block_uniform_array_element(const std::string &blockName, const std::string &uniformName, int arrayIndex, const void *value)
Definition: shader_program.cpp:376
int program_output(const std::string &name) const
Definition: shader_program.cpp:316
void clear()
Removes (deletes) all shaders.
Definition: shader_program.cpp:113
bool is_bound() const
Returns true if the program is being used (i.e., between bind() and release()).
Definition: shader_program.cpp:662
ShaderProgram * set_block_uniform(const std::string &blockName, const std::string &uniformName, const void *value)
Definition: shader_program.cpp:355
Definition: collider.cpp:182