Skip to main content

OpenGLShaderCompileManager.ixx File

OpenGL manager that compiles shader sources into native OpenGL programs. More...

Included Headers

#include <glad/gl.h> #include <GLFW/glfw3.h> #include <cassert> #include <iostream> #include <memory> #include <ostream> #include <ranges> #include <unordered_map> #include <vector> #include <helios.engine.runtime.concepts> #include <helios.engine.runtime.messaging.command.CommandHandlerRegistry> #include <helios.engine.runtime.messaging.command.NullCommandBuffer> #include <helios.engine.runtime.messaging.command.concepts> #include <helios.engine.rendering.shader.commands> #include <helios.engine.rendering.shader.types> #include <helios.engine.runtime.world.tags> #include <helios.engine.util.log> #include <helios.engine.runtime.world> #include <helios.engine.rendering.shader.components> #include <helios.engine.rendering.shader.ShaderEntity> #include <helios.engine.util.io> #include <helios.engine.rendering.shader.concepts> #include <helios.engine.rendering.shader.NullUniformCacheStrategy> #include <helios.opengl.components.OpenGLShaderComponent> #include <helios.engine.runtime.world.EngineWorld>

Namespaces Index

namespacehelios
namespaceopengl
namespacecommands

Classes Index

classOpenGLShaderCompileManager<THandle, TUniformCacheStrategy>

Manager that consumes shader compile commands and performs OpenGL compilation/linking. More...

Macro Definitions Index

#defineHELIOS_LOG_SCOPE   "helios::opengl::OpenGLShaderCompileManager"

Description

OpenGL manager that compiles shader sources into native OpenGL programs.

Macro Definitions

HELIOS_LOG_SCOPE

#define HELIOS_LOG_SCOPE   "helios::opengl::OpenGLShaderCompileManager"

Definition at line 53 of file OpenGLShaderCompileManager.ixx.

53#define HELIOS_LOG_SCOPE "helios::opengl::OpenGLShaderCompileManager"

File Listing

The file content with the documentation metadata removed is:

1
5module;
6
7#include <glad/gl.h>
8#include <GLFW/glfw3.h>
9#include <cassert>
10#include <iostream>
11#include <memory>
12#include <ostream>
13#include <ranges>
14#include <unordered_map>
15#include <vector>
16
17
18export module helios.opengl.OpenGLShaderCompileManager;
19
20import helios.engine.util.log;
21import helios.engine.util.io;
22import helios.engine.runtime.world.tags;
23import helios.engine.runtime.world;
24import helios.engine.rendering.shader.commands;
25import helios.engine.rendering.shader.components;
26import helios.engine.rendering.shader.ShaderEntity;
27import helios.engine.rendering.shader.types;
28import helios.engine.rendering.shader.concepts;
29import helios.engine.rendering.shader.commands;
30import helios.engine.rendering.shader.NullUniformCacheStrategy;
31
32import helios.opengl.components.OpenGLShaderComponent;
33
34import helios.engine.runtime.world.EngineWorld;
35import helios.engine.runtime.messaging.command.concepts;
36import helios.engine.runtime.messaging.command.NullCommandBuffer;
37import helios.engine.runtime.messaging.command.CommandHandlerRegistry;
38import helios.engine.runtime.concepts;
39
40using namespace helios::engine::runtime::world;
41using namespace helios::engine::util::log;
42using namespace helios::engine::util::io;
43using namespace helios::engine::runtime::world::tags;
44using namespace helios::engine::rendering::shader::commands;
45using namespace helios::engine::rendering::shader::components;
46using namespace helios::engine::rendering::shader;
47using namespace helios::engine::rendering::shader::types;
48using namespace helios::engine::rendering::shader::concepts;
49using namespace helios::engine::rendering::shader::commands;
50using namespace helios::opengl::components;
51using namespace helios::engine::runtime::messaging::command::concepts;
52using namespace helios::engine::runtime::messaging::command;
53#define HELIOS_LOG_SCOPE "helios::opengl::OpenGLShaderCompileManager"
54export namespace helios::opengl {
55
62 template<typename THandle, typename TUniformCacheStrategy = NullUniformCacheStrategy<THandle>>
63 requires IsShaderHandle<THandle> &&
64 IsUniformCacheStrategyLike<
65 TUniformCacheStrategy, THandle, UniformScope::Pass, UniformScope::Material, UniformScope::Draw
66 >
68
72 BasicStringFileReader stringFileReader_;
73
77 RenderResourceWorld& renderResourceWorld_;
78
82 std::vector<ShaderHandle> shaderHandles_;
83
87 std::string vertexShaderSource_;
88
92 std::string fragmentShaderSource_;
93
94
98 inline static const Logger& logger_ = LogManager::loggerForScope(HELIOS_LOG_SCOPE);
99
103 TUniformCacheStrategy uniformCacheStrategy_;
104
116 bool load(
117 const std::string& vertexShaderPath,
118 const std::string& fragmentShaderPath,
119 std::string& vertexShaderSource,
120 std::string& fragmentShaderSource
121 ) noexcept {
122
123 const bool frag = stringFileReader_.readInto(fragmentShaderPath, fragmentShaderSource);
124 const bool vert = stringFileReader_.readInto(vertexShaderPath, vertexShaderSource);
125
126 assert(frag && vert && "Could not load shader files");
127
128 return frag && vert;
129 }
130
131
140 bool compile(ShaderEntity shader) noexcept {
141
142 using Handle = typename ShaderEntity::Handle_type;
143
144 logger_.info("Compiling shader...");
145
146 if (shader.template get<OpenGLShaderComponent<Handle>>()) {
147 logger_.error("Shader already has a ShaderComponent");
148 assert(false && "Shader already has a ShaderComponent");
149 return false;
150 }
151
152 auto* shaderSourceComponent = shader.template get<ShaderSourceComponent<Handle>>();
153
154
155 const bool loaded = load(
156 shaderSourceComponent->vertexShaderPath,
157 shaderSourceComponent->fragmentShaderPath,
158 vertexShaderSource_, fragmentShaderSource_);
159
160 if (!loaded) {
161 logger_.error("Could not load shader files");
162 assert(false && "Could not load shader files");
163 return false;
164 }
165
166 const GLchar* vertexSrc = vertexShaderSource_.c_str();
167 const GLchar* fragmentSrc = fragmentShaderSource_.c_str();
168
169 const unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
170 glShaderSource(vertexShader, 1, &vertexSrc, nullptr);
171 glCompileShader(vertexShader);
172
173 const unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
174 glShaderSource(fragmentShader, 1, &fragmentSrc, nullptr);
175 glCompileShader(fragmentShader);
176
177 int success;
178 char infoLog[512];
179
180 glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
181 if (!success) {
182 glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog);
183 logger_.error("Vertex Shader Compilation failed.");
184 assert(false && "Vertex Shader Compilation failed.");
185 return false;
186 }
187
188 glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
189 if (!success) {
190 glGetShaderInfoLog(fragmentShader, 512, nullptr, infoLog);
191 logger_.error("Fragment Shader Compilation failed.");
192 assert(false && "Fragment Shader Compilation failed.");
193 return false;
194 }
195
196 auto progId = glCreateProgram();
197
198 glAttachShader(progId, vertexShader);
199 glAttachShader(progId, fragmentShader);
200 glLinkProgram(progId);
201
202 glGetProgramiv(progId, GL_LINK_STATUS, &success);
203 if (!success) {
204 glGetProgramInfoLog(progId, 512, nullptr, infoLog);
205 logger_.error("Program linking failed.");
206 assert(false && "Program linking failed.");
207 return false;
208 }
209
210 auto& shaderComponent = shader.add<OpenGLShaderComponent<THandle>>();
211 shaderComponent.programId = progId;
212
213 glDeleteShader(vertexShader);
214 glDeleteShader(fragmentShader);
215
216 vertexShaderSource_.clear();
217 fragmentShaderSource_.clear();
218
219 return true;
220 }
221
222 public:
223
231 RenderResourceWorld& renderResourceWorld,
232 TUniformCacheStrategy&& uniformCacheStrategy
233 )
234 :
235 renderResourceWorld_(renderResourceWorld),
236 uniformCacheStrategy_(std::move(uniformCacheStrategy))
237 { }
238
242 using EngineRoleTag = ManagerRole;
243
244
253 void flush(UpdateContext& updateContext) noexcept {
254
255 if (shaderHandles_.empty()) {
256 return;
257 }
258
259 for (const auto& sourceHandle : shaderHandles_) {
260 auto shaderEntity = renderResourceWorld_.findEntity<THandle>(sourceHandle);
261
262 if (!shaderEntity) {
263 logger_.error("Could not find shader source");
264 assert(false && "Could not find shader source");
265 continue;
266 }
267
268 if (!compile(*shaderEntity)) {
269 logger_.error("Could not compile shader");
270 } else {
271 shaderEntity->template remove<ShaderSourceComponent<THandle>>();
272 std::ignore = uniformCacheStrategy_.template cacheUniforms<UniformScope::Pass>(shaderEntity->handle(), renderResourceWorld_, updateContext);
273 std::ignore = uniformCacheStrategy_.template cacheUniforms<UniformScope::Material>(shaderEntity->handle(), renderResourceWorld_, updateContext);
274 std::ignore = uniformCacheStrategy_.template cacheUniforms<UniformScope::Draw>(shaderEntity->handle(), renderResourceWorld_, updateContext);
275
276 }
277 }
278
279 shaderHandles_.clear();
280 }
281
288 bool submit(ShaderBatchCompileCommand<THandle>&& command) noexcept {
289 shaderHandles_.reserve(shaderHandles_.size() + command.shaderHandles.size());
290
291 for (auto& shaderHandle : command.shaderHandles) {
292 shaderHandles_.push_back(std::move(shaderHandle));
293 }
294 return true;
295 }
296
303 bool submit(ShaderCompileCommand<THandle>&& command) noexcept {
304 shaderHandles_.push_back(std::move(command.shaderHandle));
305 return true;
306 }
307
313 void init(helios::engine::runtime::messaging::command::CommandHandlerRegistry& commandHandlerRegistry) noexcept {
314 commandHandlerRegistry.registerHandler<ShaderCompileCommand<THandle>>(*this);
315 commandHandlerRegistry.registerHandler<ShaderBatchCompileCommand<THandle>>(*this);
316 }
317 };
318
319
320}

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.9.8.