#pragma once #include "../draw_queue.h" #include "../ground/grass_gpu.h" #include "../ground/plant_gpu.h" #include "../ground/stone_gpu.h" #include "../ground/terrain_gpu.h" #include "camera.h" #include "persistent_buffer.h" #include "resources.h" #include "shader.h" #include "shader_cache.h" #include #include #include #include #include #include namespace Render::GL::BackendPipelines { class CylinderPipeline; class VegetationPipeline; class TerrainPipeline; class CharacterPipeline; class WaterPipeline; class EffectsPipeline; class PrimitiveBatchPipeline; class BannerPipeline; class HealingBeamPipeline; class HealerAuraPipeline; class CombatDustPipeline; class RainPipeline; class ModeIndicatorPipeline; class MeshInstancingPipeline; } // namespace Render::GL::BackendPipelines namespace Render::GL { class Backend : protected QOpenGLFunctions_3_3_Core { public: friend class BackendPipelines::CylinderPipeline; friend class BackendPipelines::VegetationPipeline; Backend(); ~Backend() override; Backend(const Backend &) = delete; auto operator=(const Backend &) -> Backend & = delete; Backend(Backend &&) = delete; auto operator=(Backend &&) -> Backend & = delete; void initialize(); void begin_frame(); void set_viewport(int w, int h); void set_clear_color(float r, float g, float b, float a); void set_animation_time(float time) { m_animationTime = time; } void execute(const DrawQueue &queue, const Camera &cam); [[nodiscard]] auto resources() const -> ResourceManager * { return m_resources.get(); } [[nodiscard]] auto shader(const QString &name) const -> Shader * { return m_shaderCache ? m_shaderCache->get(name) : nullptr; } auto get_or_load_shader(const QString &name, const QString &vert_path, const QString &fragPath) -> Shader * { if (!m_shaderCache) { return nullptr; } return m_shaderCache->load(name, vert_path, fragPath); } [[nodiscard]] auto banner_mesh() const -> Mesh *; [[nodiscard]] auto banner_shader() const -> Shader *; [[nodiscard]] auto healing_beam_pipeline() -> BackendPipelines::HealingBeamPipeline * { return m_healingBeamPipeline.get(); } [[nodiscard]] auto healer_aura_pipeline() -> BackendPipelines::HealerAuraPipeline * { return m_healerAuraPipeline.get(); } [[nodiscard]] auto combat_dust_pipeline() -> BackendPipelines::CombatDustPipeline * { return m_combatDustPipeline.get(); } [[nodiscard]] auto rain_pipeline() -> BackendPipelines::RainPipeline * { return m_rainPipeline.get(); } [[nodiscard]] auto mode_indicator_pipeline() -> BackendPipelines::ModeIndicatorPipeline * { return m_modeIndicatorPipeline.get(); } void enable_depth_test(bool enable) { if (enable) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } } void set_depth_func(GLenum func) { glDepthFunc(func); } void set_depth_mask(bool write) { glDepthMask(write ? GL_TRUE : GL_FALSE); } void enable_blend(bool enable) { if (enable) { glEnable(GL_BLEND); } else { glDisable(GL_BLEND); } } void set_blend_func(GLenum src, GLenum dst) { glBlendFunc(src, dst); } void enable_polygon_offset(bool enable) { if (enable) { glEnable(GL_POLYGON_OFFSET_FILL); } else { glDisable(GL_POLYGON_OFFSET_FILL); } } void set_polygon_offset(float factor, float units) { glPolygonOffset(factor, units); } void set_riverbank_visibility(bool enabled, Texture *texture, const QVector2D &size, float tile_size, float explored_alpha) { m_riverbankVisibility.enabled = enabled && (texture != nullptr); m_riverbankVisibility.texture = texture; m_riverbankVisibility.size = size; m_riverbankVisibility.tile_size = tile_size; m_riverbankVisibility.explored_alpha = explored_alpha; } private: int m_viewportWidth{0}; int m_viewportHeight{0}; std::array m_clearColor{0.2F, 0.3F, 0.3F, 0.0F}; std::unique_ptr m_shaderCache; std::unique_ptr m_resources; std::unique_ptr m_cylinderPipeline; std::unique_ptr m_vegetationPipeline; std::unique_ptr m_terrainPipeline; std::unique_ptr m_characterPipeline; std::unique_ptr m_waterPipeline; std::unique_ptr m_effectsPipeline; std::unique_ptr m_primitiveBatchPipeline; std::unique_ptr m_bannerPipeline; std::unique_ptr m_healingBeamPipeline; std::unique_ptr m_healerAuraPipeline; std::unique_ptr m_combatDustPipeline; std::unique_ptr m_rainPipeline; std::unique_ptr m_modeIndicatorPipeline; std::unique_ptr m_meshInstancingPipeline; Shader *m_basicShader = nullptr; Shader *m_gridShader = nullptr; Shader *m_shadowShader = nullptr; Shader *m_lastBoundShader = nullptr; Texture *m_lastBoundTexture = nullptr; bool m_depth_testEnabled = true; bool m_blendEnabled = false; float m_animationTime = 0.0F; struct { Texture *texture = nullptr; QVector2D size{0.0F, 0.0F}; float tile_size = 1.0F; float explored_alpha = 0.6F; bool enabled = false; } m_riverbankVisibility; }; } // namespace Render::GL