Simulant  21.09-46
A portable game engine for Windows, OSX, Linux, Dreamcast, and PSP
gpu_program.h
1 /* * Copyright (c) 2011-2017 Luke Benstead https://simulant-engine.appspot.com
2  *
3  * This file is part of Simulant.
4  *
5  * Simulant is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * Simulant is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with Simulant. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef GPU_PROGRAM_H
20 #define GPU_PROGRAM_H
21 
22 #include <set>
23 #include <map>
24 #include <unordered_map>
25 
26 #include "../../signals/signal.h"
27 #include "../../types.h"
28 #include "../../generic/property.h"
29 #include "../../generic/managed.h"
30 #include "../../utils/gl_thread_check.h"
31 #include "../../generic/identifiable.h"
32 #include "../../vertex_data.h"
33 
34 #include "../glad/glad/glad.h"
35 
36 #define BUFFER_OFFSET(bytes) ((GLubyte*) NULL + (bytes))
37 
38 namespace std {
39  using smlt::ShaderType;
40 
41  template<>
42  struct hash<ShaderType> {
43  size_t operator()(const ShaderType& a) const {
44  hash<int32_t> make_hash;
45  return make_hash(int32_t(a));
46  }
47  };
48 }
49 
50 class ShaderTest;
51 
52 namespace smlt {
53 
54 class Renderer;
55 class GPUProgram;
56 
57 typedef sig::signal<void ()> ProgramLinkedSignal;
58 typedef sig::signal<void (ShaderType)> ShaderCompiledSignal;
59 
60 struct UniformInfo {
61  unicode name;
62  GLenum type;
63  GLsizei size;
64 };
65 
66 
67 class GPUProgram:
68  public RefCounted<GPUProgram>,
69  public generic::Identifiable<GPUProgramID> {
70 
71 public:
72  friend class Renderer;
73 
74  GPUProgram(const GPUProgramID& id, Renderer* renderer, const std::string& vertex_source, const std::string& fragment_source);
75  GPUProgram(const GPUProgram&) = delete;
76  GPUProgram& operator=(const GPUProgram&) = delete;
77 
78  bool init() override;
79  void clean_up() override;
80 
81  bool is_current() const;
82  void activate();
83 
84  bool is_complete() const;
85  bool is_compiled(ShaderType type) const;
86 
87  void compile(ShaderType type);
88  void build();
89 
90  ProgramLinkedSignal& signal_linked() { return signal_linked_; }
91  ShaderCompiledSignal& signal_shader_compiled() { return signal_shader_compiled_; }
92 
93  std::string md5() { return md5_shader_hash_; }
94 
95  struct ShaderInfo {
96  uint32_t object = 0;
97  bool is_compiled = false;
98  std::string source;
99  };
100 
101  const std::unordered_map<ShaderType, ShaderInfo> shader_infos() const { return shaders_; }
102 
103  GLint locate_uniform(const std::string& name, bool fail_silently=false);
104  GLint locate_attribute(const std::string& name, bool fail_silently=false);
105  void set_uniform_location(const std::string& name, GLint location);
106  void set_attribute_location(const std::string& name, GLint location);
107 
108  UniformInfo uniform_info(const std::string& uniform_name);
109 
110  void clear_cache() {
111  uniform_cache_.clear();
112  }
113 
114  void set_uniform_int(const int32_t loc, const int32_t value);
115  void set_uniform_mat4x4(const int32_t loc, const Mat4& values);
116  void set_uniform_colour(const int32_t loc, const Colour& values);
117  void set_uniform_vec4(const int32_t loc, const Vec4& values);
118  void set_uniform_float(const int32_t loc, const float value);
119 
120  void set_uniform_int(const std::string& uniform_name, const int32_t value, bool fail_silently=false);
121  void set_uniform_float(const std::string& uniform_name, const float value, bool fail_silently=false);
122  void set_uniform_mat4x4(const std::string& uniform_name, const Mat4& values);
123  void set_uniform_mat3x3(const std::string& uniform_name, const Mat3& values);
124  void set_uniform_vec3(const std::string& uniform_name, const Vec3& values);
125  void set_uniform_vec4(const std::string& uniform_name, const Vec4& values);
126  void set_uniform_colour(const std::string& uniform_name, const Colour& values);
127  void set_uniform_mat4x4_array(const std::string& uniform_name, const std::vector<Mat4>& matrices);
128 
129  void relink() {
130  if(needs_relink_) {
131  link();
132  needs_relink_ = false;
133  }
134  }
135 
136  GLuint program_object() const { return program_object_; }
137  void prepare_program();
138 
139  void _set_renderer_specific_id(uint32_t id) {
140  renderer_id_ = id;
141  }
142 
143  uint32_t _renderer_specific_id() const {
144  return renderer_id_;
145  }
146 
147 private:
148  friend class ::ShaderTest;
149 
150  Renderer* renderer_;
151 
152  std::unordered_map<unicode, UniformInfo> uniform_info_;
153 
154  void rebuild_uniform_info();
155  void set_shader_source(ShaderType type, const std::string &source);
156 
157  bool is_linked_ = false;
158  bool needs_relink_ = true;
159 
160  uint32_t program_object_ = 0;
161  std::unordered_map<ShaderType, ShaderInfo> shaders_;
162  std::unordered_map<ShaderType, std::string> shader_hashes_;
163 
164  ProgramLinkedSignal signal_linked_;
165  ShaderCompiledSignal signal_shader_compiled_;
166 
167  //A hash of all the GLSL shaders so we can uniquely identify a program
168  void rebuild_hash();
169  std::string md5_shader_hash_;
170 
171  std::unordered_map<std::string, GLint> uniform_cache_;
172  std::unordered_map<std::string, int32_t> attribute_cache_;
173 
174  void link(bool force=false);
175 
176  uint32_t renderer_id_ = 0;
177 };
178 
179 
180 }
181 #endif // GPU_PROGRAM_H
smlt::GPUProgram
Definition: gpu_program.h:69
smlt::RefCounted
Definition: managed.h:65
smlt
Definition: animation.cpp:25
smlt::GPUProgram::ShaderInfo
Definition: gpu_program.h:95
smlt::generic::Identifiable
Definition: identifiable.h:26
smlt::UniqueID< GPUProgramPtr >
smlt::UniformInfo
Definition: gpu_program.h:60
unicode
Definition: unicode.h:35
smlt::Renderer
Definition: renderer.h:40
std
Extensions to the C++ standard library.
Definition: unique_id.h:200
smlt::sig::signal< void()>