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
namespacecomponents

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> && IsUniformCacheStrategyLike<TUniformCacheStrategy, THandle, UniformScope::Pass, UniformScope::Draw>
65
66 BasicStringFileReader stringFileReader_;
67
68 RenderResourceWorld& renderResourceWorld_;
69
70 std::vector<ShaderHandle> shaderHandles_;
71
72 std::string vertexShaderSource_;
73
74 std::string fragmentShaderSource_;
75
76
77 inline static const Logger& logger_ = LogManager::loggerForScope(HELIOS_LOG_SCOPE);
78
79 TUniformCacheStrategy uniformCacheStrategy_;
80
88 bool load(
89 const std::string& vertexShaderPath,
90 const std::string& fragmentShaderPath,
91 std::string& vertexShaderSource,
92 std::string& fragmentShaderSource
93 ) noexcept {
94
95 const bool frag = stringFileReader_.readInto(fragmentShaderPath, fragmentShaderSource);
96 const bool vert = stringFileReader_.readInto(vertexShaderPath, vertexShaderSource);
97
98 assert(frag && vert && "Could not load shader files");
99
100 return frag && vert;
101 }
102
103
111 bool compile(ShaderEntity shader) noexcept {
112
113 using Handle = typename ShaderEntity::Handle_type;
114
115 logger_.info("Compiling shader...");
116
117 if (shader.template get<OpenGLShaderComponent<Handle>>()) {
118 logger_.error("Shader already has a ShaderComponent");
119 assert(false && "Shader already has a ShaderComponent");
120 return false;
121 }
122
123 auto* shaderSourceComponent = shader.template get<ShaderSourceComponent<Handle>>();
124
125
126 const bool loaded = load(
127 shaderSourceComponent->vertexShaderPath,
128 shaderSourceComponent->fragmentShaderPath,
129 vertexShaderSource_, fragmentShaderSource_);
130
131 if (!loaded) {
132 logger_.error("Could not load shader files");
133 assert(false && "Could not load shader files");
134 return false;
135 }
136
137 const GLchar* vertexSrc = vertexShaderSource_.c_str();
138 const GLchar* fragmentSrc = fragmentShaderSource_.c_str();
139
140 const unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
141 glShaderSource(vertexShader, 1, &vertexSrc, nullptr);
142 glCompileShader(vertexShader);
143
144 const unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
145 glShaderSource(fragmentShader, 1, &fragmentSrc, nullptr);
146 glCompileShader(fragmentShader);
147
148 int success;
149 char infoLog[512];
150
151 glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
152 if (!success) {
153 glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog);
154 logger_.error("Vertex Shader Compilation failed.");
155 assert(false && "Vertex Shader Compilation failed.");
156 return false;
157 }
158
159 glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
160 if (!success) {
161 glGetShaderInfoLog(fragmentShader, 512, nullptr, infoLog);
162 logger_.error("Fragment Shader Compilation failed.");
163 assert(false && "Fragment Shader Compilation failed.");
164 return false;
165 }
166
167 auto progId = glCreateProgram();
168
169 glAttachShader(progId, vertexShader);
170 glAttachShader(progId, fragmentShader);
171 glLinkProgram(progId);
172
173 glGetProgramiv(progId, GL_LINK_STATUS, &success);
174 if (!success) {
175 glGetProgramInfoLog(progId, 512, nullptr, infoLog);
176 logger_.error("Program linking failed.");
177 assert(false && "Program linking failed.");
178 return false;
179 }
180
181 auto& shaderComponent = shader.add<OpenGLShaderComponent<THandle>>();
182 shaderComponent.programId = progId;
183
184 glDeleteShader(vertexShader);
185 glDeleteShader(fragmentShader);
186
187 vertexShaderSource_.clear();
188 fragmentShaderSource_.clear();
189
190 return true;
191 }
192
193 public:
194
201 RenderResourceWorld& renderResourceWorld,
202 TUniformCacheStrategy&& uniformCacheStrategy
203 )
204 :
205 renderResourceWorld_(renderResourceWorld),
206 uniformCacheStrategy_(std::move(uniformCacheStrategy))
207 { }
208
212 using EngineRoleTag = ManagerRole;
213
214
220 void flush(UpdateContext& updateContext) noexcept {
221
222 if (shaderHandles_.empty()) {
223 return;
224 }
225
226 for (const auto& sourceHandle : shaderHandles_) {
227 auto shaderEntity = renderResourceWorld_.findEntity<THandle>(sourceHandle);
228
229 if (!shaderEntity) {
230 logger_.error("Could not find shader source");
231 assert(false && "Could not find shader source");
232 continue;
233 }
234
235 if (!compile(*shaderEntity)) {
236 logger_.error("Could not compile shader");
237 } else {
238 shaderEntity->template remove<ShaderSourceComponent<THandle>>();
239 uniformCacheStrategy_.template cacheUniforms<UniformScope::Pass>(shaderEntity->handle(), renderResourceWorld_, updateContext);
240 uniformCacheStrategy_.template cacheUniforms<UniformScope::Draw>(shaderEntity->handle(), renderResourceWorld_, updateContext);
241 }
242 }
243
244 shaderHandles_.clear();
245 }
246
247 bool submit(const ShaderBatchCompileCommand<THandle>& command) noexcept {
248 for (const auto& shaderHandle : command.shaderHandles) {
249 shaderHandles_.push_back(shaderHandle);
250 }
251 return true;
252 }
253
254 bool submit(const ShaderCompileCommand<THandle>& command) noexcept {
255 shaderHandles_.push_back(command.shaderHandle);
256 return true;
257 }
258
264 void init(helios::engine::runtime::messaging::command::CommandHandlerRegistry& commandHandlerRegistry) noexcept {
265 commandHandlerRegistry.registerHandler<ShaderCompileCommand<THandle>>(*this);
266 commandHandlerRegistry.registerHandler<ShaderBatchCompileCommand<THandle>>(*this);
267 }
268 };
269
270
271}

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.9.8.