OpenGL backend for render-pass execution and indexed draw submission. More...
#include <glad/gl.h>
#include <GLFW/glfw3.h>
#include <memory>
#include <cassert>
#include <utility>
#include <type_traits>
#include <span>
#include "
helios-opengl-config.h"
#include <optional>
#include <helios.engine.runtime.world.EngineWorld>
#include <
helios.opengl.types>
#include <helios.engine.scene.components>
#include <helios.engine.util.Colors>
#include <helios.math>
#include <helios.engine.rendering.common.types>
#include <helios.engine.rendering.viewport>
#include <helios.engine.rendering.material>
#include <helios.engine.util.log>
#include <helios.engine.rendering.viewport.ViewportEntity>
#include <
helios.opengl.OpenGLUniformWriter>
#include <
helios.opengl.components>
#include <helios.engine.rendering.mesh>
#include <helios.engine.rendering.renderTarget.RenderTargetEntity>
#include <helios.engine.rendering.common.components>
#include <helios.engine.rendering.renderTarget>
#include <helios.engine.spatial.components>
#include <helios.engine.core.components>
#include <helios.engine.scene.types>
#include <helios.engine.rendering.shader>
Namespaces Index
| namespace | helios |
|
|
|
| namespace | opengl |
|
|
|
| namespace | rendering |
|
|
|
| namespace | components |
|
|
|
| namespace | shader |
|
|
|
| namespace | components |
|
|
|
| namespace | types |
|
|
|
| namespace | types |
|
|
|
| namespace | components |
|
|
|
| namespace | renderTarget |
|
|
|
| namespace | types |
|
|
|
| namespace | viewport |
|
|
|
| namespace | types |
|
|
|
| namespace | components |
|
|
|
| namespace | types |
|
|
|
| namespace | world |
|
|
|
| namespace | log |
|
|
|
Classes Index
Macro Definitions Index
Description
OpenGL backend for render-pass execution and indexed draw submission.
Macro Definitions
HELIOS_LOG_SCOPE
| #define HELIOS_LOG_SCOPE "helios::opengl" |
|
File Listing
The file content with the documentation metadata removed is:
17export module helios.opengl.OpenGLBackend;
21import helios.engine.util.log;
23import helios.engine.rendering.viewport.ViewportEntity;
25import helios.engine.rendering.renderTarget.RenderTargetEntity;
26import helios.engine.rendering.common.types;
27import helios.engine.rendering.common.components;
29import helios.engine.spatial.components;
31import helios.engine.core.components;
33import helios.opengl.OpenGLUniformWriter;
34import helios.opengl.components;
35import helios.opengl.types;
38import helios.engine.rendering.mesh;
39import helios.engine.rendering.shader;
40import helios.engine.rendering.material;
41import helios.engine.rendering.renderTarget;
42import helios.engine.rendering.viewport;
43import helios.engine.util.Colors;
45import helios.engine.scene.components;
46import helios.engine.scene.types;
48import helios.engine.runtime.world.EngineWorld;
50import helios.opengl.types;
52using namespace helios::engine::core::components;
53using namespace helios::engine::rendering;
54using namespace helios::engine::rendering::mesh::components;
55using namespace helios::engine::rendering::shader;
56using namespace helios::engine::rendering::shader::types;
60using namespace helios::engine::spatial::components;
61using namespace helios::engine::rendering::material::types;
62using namespace helios::engine::rendering::common::types;
63using namespace helios::engine::rendering::common::components;
64using namespace helios::engine::rendering::mesh::types;
65using namespace helios::engine::rendering::renderTarget;
66using namespace helios::engine::rendering::renderTarget::types;
67using namespace helios::engine::rendering::viewport;
68using namespace helios::engine::rendering::viewport::types;
69using namespace helios::engine::scene::components;
70using namespace helios::engine::scene::types;
71using namespace helios::engine::runtime::world;
72using namespace helios::engine::util::log;
74#define HELIOS_LOG_SCOPE "helios::opengl"
91 bool isInitialized_ = false;
93 inline static const helios::engine::util::log::Logger& logger_ = helios::engine::util::log::LogManager::loggerForScope(
105 UniformValueBag<UniformScope::Pass> passUniformValueBag_{};
110 UniformValueBag<UniformScope::Draw> drawUniformValueBag_{};
115 RenderTargetHandle currentRenderTargetHandle_{};
120 ShaderHandle currentShaderHandle_{};
126 EngineWorld& engineWorld_;
131 struct ViewProjection {
132 helios::math::mat4f viewMatrix;
133 helios::math::mat4f projectionMatrix;
143 [[nodiscard]] std::optional<ViewProjection> viewProjection(const ViewportEntity& vieportEntity) const noexcept {
145 auto* cbc = vieportEntity.get<CameraBindingComponent<ViewportHandle>>();
147 logger_.error("Expected CameraBindingComponent on ViewportEntity, but couldn't find any.");
150 auto camera = engineWorld_.find(cbc->targetHandle());
152 logger_.error("Expected CameraEntity, but couldn't find any.");
155 using CameraHandleType = std::remove_cvref_t<decltype(cbc->targetHandle())>;
156 auto* vm = camera->get<ViewMatrixComponent<CameraHandleType>>();
158 logger_.error("Expected ViewMatrixComponent, but couldn't find any.");
162 auto* pm = camera->get<ProjectionMatrixComponent<CameraHandleType>>();
164 logger_.error("Expected ProjectionMatrixComponent, but couldn't find any.");
168 return ViewProjection{
169 vm->value(), pm->value()
186 template<typename TUniformScope>
187 void writeUniformValues(ShaderEntity shaderEntity, UniformValueBag<TUniformScope>& uniformValueBag) noexcept {
192 logger_.error("OpenGLUniformWritePlanComponent<{0}> expected, but not found", typeid(TUniformScope).name());
193 assert(false && "OpenGLUniformWritePlanComponent not found");
209 template<typename THandle, typename TEntity>
210 void clearColor(TEntity& entity) noexcept {
212 auto* colorComp = entity->template get<ColorComponent<THandle>>();
213 auto* clearComp = entity->template get<ClearComponent<THandle>>();
216 const auto clearColor = colorComp->value();
217 glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
221 const auto clearFlags = std::to_underlying(clearComp->flags);
222 const auto clearMask = ((clearFlags & std::to_underlying(ClearFlags::Color)) ? GL_COLOR_BUFFER_BIT : 0) |
223 ((clearFlags & std::to_underlying(ClearFlags::Depth)) ? GL_DEPTH_BUFFER_BIT : 0) |
224 ((clearFlags & std::to_underlying(ClearFlags::Stencil)) ? GL_STENCIL_BUFFER_BIT : 0);
226 if (clearMask != 0) {
242 explicit OpenGLBackend(EngineWorld& engineWorld) : engineWorld_(engineWorld){}
255 auto renderTargetEntity = engineWorld_.find<RenderTargetHandle>(renderTargetHandle);
258 if (!renderTargetEntity) {
259 logger_.error("Missing RenderTargetEntity for handle {0}.", renderTargetHandle.entityId);
260 assert(renderTargetEntity && "Missing RenderTargetEntity for handle.");
264 currentRenderTargetHandle_ = renderTargetHandle;
268 glBindFramebuffer(GL_FRAMEBUFFER, renderTargetId);
271 const auto isValidRenderTarget = renderTargetId == 0 ||
272 (glIsFramebuffer(renderTargetId) == GL_TRUE && glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
273 if (!isValidRenderTarget) {
274 logger_.error("RenderTargetEntity with EntityId {0} undefined.", renderTargetId);
275 assert(isValidRenderTarget && "RenderTargetEntity EntityId does not seem to be a valid id.");
279 auto renderTargetSize = renderTargetEntity->get<Size2DComponent<RenderTargetHandle>>()->value();
282 static_cast<int>(renderTargetSize[0]),
283 static_cast<int>(renderTargetSize[1])
286 clearColor<RenderTargetHandle>(renderTargetEntity);
291 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
303 currentRenderTargetHandle_ = RenderTargetHandle{};
304 passUniformValueBag_.clearValues();
305 drawUniformValueBag_.clearValues();
318 auto viewport = engineWorld_.find<ViewportHandle>(viewportHandle);
319 auto renderTargetEntity = engineWorld_.find<RenderTargetHandle>(currentRenderTargetHandle_);
322 if (!renderTargetEntity) {
323 logger_.error("Missing RenderTargetEntity for handle {0}.", renderTargetEntity->handle().entityId);
324 assert(renderTargetEntity && "Missing RenderTargetEntity for handle.");
327 logger_.error("Missing Viewport for handle {0}.", viewportHandle.entityId);
328 assert(viewport && "Missing Viewport for handle.");
332 auto vp = viewProjection(*viewport);
334 logger_.warn("Could not determine View/Projection-matrices for RenderPass");
335 passUniformValueBag_.set<ProjectionMatrixUniform>(helios::math::mat4f{1.0f});
336 passUniformValueBag_.set<ViewMatrixUniform>(helios::math::mat4f{1.0f});
338 passUniformValueBag_.set<ProjectionMatrixUniform>(vp->projectionMatrix);
339 passUniformValueBag_.set<ViewMatrixUniform>(vp->viewMatrix);
342 auto viewportBounds = viewport->get<RectComponent<ViewportHandle>>()->value();
343 auto renderTargetSize = renderTargetEntity->get<Size2DComponent<RenderTargetHandle>>()->value();
345 const auto x = static_cast<int>(renderTargetSize[0] * viewportBounds[0]);
346 const auto y = static_cast<int>(renderTargetSize[1] * viewportBounds[1]);
347 const auto width = static_cast<int>(renderTargetSize[0] * viewportBounds[2]);
348 const auto height = static_cast<int>(renderTargetSize[1] * viewportBounds[3]);
351 glViewport(x, y, width, height);
352 glScissor(x, y, width, height);
353 glEnable(GL_SCISSOR_TEST);
355 clearColor<ViewportHandle>(viewport);
364 glDisable(GL_SCISSOR_TEST);
376 auto shaderEntity = engineWorld_.find(shaderHandle);
378 logger_.error("ShaderEntity expected, but not found");
379 assert(false && "ShaderEntity not found");
383 currentShaderHandle_ = shaderHandle;
385 auto* openglShader = shaderEntity->template get<OpenGLShaderComponent<ShaderHandle>>();
387 logger_.error("OpenGLShader expected, but not found");
388 assert(false && "OpenGLShader not found");
392 glUseProgram(openglShader->programId);
393 writeUniformValues<UniformScope::Pass>(*shaderEntity, passUniformValueBag_);
402 currentShaderHandle_ = ShaderHandle{};
413 auto materialEntity = engineWorld_.find(materialHandle);
414 if (!materialEntity) {
415 logger_.error("MaterialEntity expected, but not found");
416 assert(false && "MaterialEntity not found");
420 auto* colorComponent = materialEntity->template get<ColorComponent<MaterialHandle>>();
421 if (colorComponent) {
422 drawUniformValueBag_.set<MaterialBaseColorUniform>(colorComponent->value());
445 auto meshEntity = engineWorld_.find(meshHandle);
447 logger_.error("MeshEntity expected, but not found");
448 assert(false && "MeshEntity not found");
452 auto* openglMesh = meshEntity->template get<OpenGLMeshComponent<MeshHandle>>();
454 logger_.error("OpenGLMesh expected, but not found");
455 assert(false && "OpenGLMesh not found");
458 currentOpenGLMesh_ = openglMesh;
459 glBindVertexArray(openglMesh->vao);
469 currentOpenGLMesh_ = nullptr;
470 glBindVertexArray(0);
482 template<typename THandle>
483 void renderBatch(std::span<SceneMemberRenderContext<THandle>> sceneMemberRenderContexts) noexcept {
485 if (!currentOpenGLMesh_) {
486 logger_.error("OpenGLMesh expected, but not available");
489 if (!currentShaderHandle_.isValid()) {
490 logger_.error("Expected valid currentShaderHandle_, but found {0}.", currentShaderHandle_.entityId);
494 auto shaderEntity = engineWorld_.find(currentShaderHandle_);
496 assert(shaderEntity && "ShaderEntity expected, but not found");
497 assert(currentOpenGLMesh_ && "Current OpenGL mesh expected, but not found");
499 for (auto& renderContext : sceneMemberRenderContexts) {
501 drawUniformValueBag_.set<ModelMatrixUniform>(renderContext.worldMatrix);
502 writeUniformValues<UniformScope::Draw>(*shaderEntity, drawUniformValueBag_);
521 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
522 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
523 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
534 [[nodiscard]] bool init() noexcept {
536 assert(!isInitialized_ && "Backend already initialized");
538 const GLADloadfunc procAddressLoader = glfwGetProcAddress;
539 const int gl_ver = gladLoadGL(procAddressLoader);
542 logger_.error("Failed to load OpenGL");
543 assert(false && "Failed to load OpenGL");
547 logger_.info("OpenGL {0}.{1} loaded", GLAD_VERSION_MAJOR(gl_ver), GLAD_VERSION_MINOR(gl_ver));
549 isInitialized_ = true;
558 return isInitialized_;
Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.9.8.