#pragma once #include #include "scene.h" #include "../platform/gl.h" #include "../lib/bbox.h" namespace Gui { class Model; } // Singleton class Renderer { public: static void setup(Vec2 dim); static void shutdown(); static Renderer& get(); void begin(); void complete(); void reset_depth(); void proj(const Mat4& proj); void update_dim(Vec2 dim); void settings_gui(bool* open); void set_samples(int samples); unsigned int read_id(Vec2 pos); struct MeshOpt { unsigned int id; Mat4 modelview; Vec3 color, sel_color, hov_color; unsigned int sel_id = 0, hov_id = 0; float alpha = 1.0f; bool wireframe = false; bool solid_color = false; bool depth_only = false; bool per_vert_id = false; }; struct HalfedgeOpt { HalfedgeOpt(Gui::Model& e) : editor(e) {} Gui::Model& editor; Mat4 modelview; Vec3 color; }; // NOTE(max): updates & uses the indices in mesh for selection/traversal void halfedge_editor(HalfedgeOpt opt); void mesh(GL::Mesh& mesh, MeshOpt opt); void lines(const GL::Lines& lines, const Mat4& view, const Mat4& model = Mat4::I, float alpha = 1.0f); void outline(const Mat4& view, Scene_Item& obj); void begin_outline(); void end_outline(const Mat4& view, BBox box); void skydome(const Mat4& rotation, Vec3 color, float cosine); void skydome(const Mat4& rotation, Vec3 color, float cosine, const GL::Tex2D& tex); void sphere(MeshOpt opt); void capsule(MeshOpt opt, float height, float rad); void capsule(MeshOpt opt, const Mat4& mdl, float height, float rad, BBox& box); GLuint saved() const; void saved(std::vector& data) const; void save(Scene& scene, const Camera& cam, int w, int h, int samples); private: Renderer(Vec2 dim); ~Renderer(); static inline Renderer* data = nullptr; GL::Framebuffer framebuffer, id_resolve, save_buffer, save_output; GL::Shader mesh_shader, line_shader, inst_shader, dome_shader; GL::Mesh _sphere, _cyl, _hemi; int samples; Vec2 window_dim; GLubyte* id_buffer; Mat4 _proj; };