#pragma once #include #include "../lib/bbox.h" #include "../platform/gl.h" #include "scene.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 f_color = Vec3{1.0f}; Vec3 v_color = Vec3{1.0f}; Vec3 e_color = Vec3{0.8f}; Vec3 he_color = Vec3{0.6f}; }; // 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; };