// 2d: Functions to render 2d things immediatly. Simple things like meshes, lines, triangles, quads.
// render: Renderer, takes complex objects with materials and renders them.
//         Might use an object buffer/queue and render things later, to enable
//         sorting and other complex rendering procedures (culling).
// shader: Shaders! They have enough code to have their own source files
// object: Objects, materials, maybe other things. To be used by the renderer.
// light:  Lights to be used by the renderer. There are enought types to separate them from objects.

// Might (or might not) add: compute shaders, vfx/postprocessing passes, animations

#ifndef _PIUMA_RENDER_RENDER_H_
#define _PIUMA_RENDER_RENDER_H_

#include "primitives.h"
#include "shader.h"
#include "2d.h"
#include "lights.h"
#include "object.h"
#include "state.h"

void r_init();
void r_deinit();

void r_size_update(u32 width, u32 height);
void r_time_update(f64 time);

void r_clear(v4 color = {0.0, 0.0, 0.0, 0.0});
void r_swap();


struct r_shadow_map
{
	// FBO + depth
	u32 gl_FBO;
	u32 gl_depth_texture;
	m4 view_matrix;
};

struct r_scene
{
	m4 view_matrix;
	m4 view_matrix_inverse;

	m4 projection_matrix;
	m4 projection_matrix_inverse;

	r_object *objects;
	u64 objects_count;

	r_light_container lights;
	GLuint gl_lights;

	r_shadow_map shadow_map;

	r_cubemap environment_map;
};

r_scene r_scene_create();
void r_scene_destroy(r_scene *scene);

void r_scene_set_view      (r_scene *scene, m4 m);
void r_scene_set_projection(r_scene *scene, m4 m);
void r_update_lights(r_scene *scene);


void r_render_scene(r_scene *scene);



// Single object rendering functions (batched funcs are below)
void r_render_object(r_scene *scene, r_object *object, r_shader *shader_override = NULL);
void r_render_object_wireframe(r_scene *scene, r_object *object);
void r_render_line(r_scene *scene, v3 a, v3 b, v4 a_color, v4 b_color, f32 thickness = 1.0);


// Batch render functions
void r_render_objects(r_scene *scene, u64 count, r_object **objects);



// Shadow maps
r_shadow_map r_build_shadow_map_sun(r_scene *scene, r_sun_light *sun);
void r_free_shadow_map(r_shadow_map *sm);


void r_framebuffer_select(r_framebuffer *fb);
void r_merge_and_postprocess();


#endif
