PortalGame/src/gfx/renderer.hpp
2025-08-29 22:22:02 +02:00

77 lines
1.8 KiB
C++

#pragma once
#include <memory>
#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> 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<VertexArray> 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);
};
}