#pragma once #include #include "gfx/shader.hpp" #include "game/world.hpp" #include "game/sector.hpp" #include "game/meshinstance.hpp" namespace gfx { struct DrawSectorParams { size_t draw_id; const game::Sector* sector; const game::Portal* entry_portal; glm::vec4 clip_plane; collision::AABB2 screen_aabb; size_t recursion; glm::mat4 view; glm::mat4 view_proj; glm::vec3 eye; }; struct SectorShader { std::unique_ptr shader; size_t setup_sector = 0; }; class Renderer { public: Renderer(); void Begin(size_t width, size_t height); void DrawWorld( const game::World& world, size_t sector_idx, const glm::vec3& eye, const glm::vec3& dir, const glm::vec3& up, float aspect, float fov); private: SectorShader sector_shader_; SectorShader portal_shader_; SectorShader mesh_shader_; std::shared_ptr portal_vao_; void SetupPortalVAO(); size_t max_portal_recursion_ = 10; // Minimum distance to portal mesh from eye // If the distance is smaller, portal plane is shifted to avoid clipping by near plane float min_portal_distance_; glm::mat4 proj_; size_t last_sector_id; const Shader* current_shader_; void UnreadyShaders(); void SetupSectorShader(const DrawSectorParams& params, SectorShader& sshader); void DrawSector(const DrawSectorParams& params); void DrawPortal(const DrawSectorParams& params, const game::Portal& portal); static bool ComputeQuadScreenAABB(const glm::vec3* verts, const glm::mat4 view_proj, collision::AABB2& aabb); void DrawPortalPlane(const DrawSectorParams& params, const game::Portal& portal, const glm::mat4& trans, bool clear_depth); void DrawMeshInstance(const DrawSectorParams& params, const game::MeshInstance& mesh_instance, const glm::mat4& model); }; }