#ifndef TWN_RENDERING_C_H #define TWN_RENDERING_C_H #include "twn_textures_c.h" #include "twn_util.h" #include "twn_option.h" #include #include #ifdef EMSCRIPTEN #include #else #include #endif #include extern t_matrix4 camera_projection_matrix; extern t_matrix4 camera_look_at_matrix; #define QUAD_ELEMENT_BUFFER_LENGTH (65536 / 6) typedef GLuint vertex_buffer; typedef struct vertex_buffer_builder { size_t bytes_left; void *mapping; } vertex_buffer_builder; struct sprite_primitive { t_frect rect; t_color color; float rotation; t_texture_key texture_key; bool flip_x; bool flip_y; bool repeat; m_option_list( t_fvec2, texture_origin ) }; struct rect_primitive { t_frect rect; t_color color; }; struct circle_primitive { float radius; t_color color; t_fvec2 position; }; struct text_primitive { t_color color; t_fvec2 position; char *text; const char *font; int height_px; }; enum primitive_2d_type { PRIMITIVE_2D_SPRITE, PRIMITIVE_2D_RECT, PRIMITIVE_2D_CIRCLE, PRIMITIVE_2D_TEXT, }; struct primitive_2d { enum primitive_2d_type type; union { struct sprite_primitive sprite; struct rect_primitive rect; struct circle_primitive circle; struct text_primitive text; }; }; /* union for in-place recalculation of texture coordinates */ union uncolored_space_triangle { /* pending for sending, uvs are not final as texture atlases could update */ struct uncolored_space_triangle_primitive { t_fvec3 v0; t_fvec2 uv0; /* in pixels */ t_fvec3 v1; t_fvec2 uv1; /* in pixels */ t_fvec3 v2; t_fvec2 uv2; /* in pixels */ } primitive; /* TODO: have it packed? */ /* structure that is passed in opengl vertex array */ struct uncolored_space_triangle_payload { t_fvec3 v0; t_fvec2 uv0; t_fvec3 v1; t_fvec2 uv1; t_fvec3 v2; t_fvec2 uv2; } payload; }; /* batch of primitives with overlapping properties */ struct mesh_batch { uint8_t *primitives; }; struct mesh_batch_item { t_texture_key key; struct mesh_batch value; }; struct text_cache { struct font_data **data; }; /* renders the background, then the primitives in all render queues */ void render(void); /* clears all render queues */ void render_queue_clear(void); void create_circle_geometry(t_fvec2 position, t_color color, float radius, size_t num_vertices, SDL_Vertex **vertices_out, int **indices_out); struct sprite_batch { size_t size; /* how many primitives are in current batch */ enum texture_mode mode; bool constant_colored; /* whether colored batch is uniformly colored */ bool repeat; /* whether repeat is needed */ } collect_sprite_batch(const struct primitive_2d primitives[], size_t len); void render_sprites(const struct primitive_2d primitives[], const struct sprite_batch batch); void draw_uncolored_space_traingle_batch(struct mesh_batch *batch, t_texture_key texture_key); /* text */ void render_text(const struct text_primitive *text); void text_cache_init(struct text_cache *cache); void text_cache_deinit(struct text_cache *cache); /* vertex buffer */ vertex_buffer create_vertex_buffer(void); void delete_vertex_buffer(vertex_buffer buffer); void specify_vertex_buffer(vertex_buffer buffer, void *data, size_t bytes); /* uses present in 1.5 buffer mapping feature */ vertex_buffer_builder build_vertex_buffer(vertex_buffer buffer, size_t bytes); /* collects bytes for sending to the gpu until all is pushed, which is when false is returned */ bool push_to_vertex_buffer_builder(vertex_buffer_builder *builder, void *bytes, size_t size); /* state */ void setup_viewport(int x, int y, int width, int height); void clear_draw_buffer(void); void swap_buffers(void); void set_depth_range(double low, double high); void bind_quad_element_buffer(void); void render_circle(const struct circle_primitive *circle); void render_rectangle(const struct rect_primitive *rectangle); void use_space_pipeline(void); void use_2d_pipeline(void); void use_texture_mode(enum texture_mode mode); void finally_render_sprites(struct primitive_2d const primitives[], struct sprite_batch batch, vertex_buffer buffer); size_t get_sprite_payload_size(struct sprite_batch batch); bool push_sprite_payload_to_vertex_buffer_builder(struct sprite_batch batch, vertex_buffer_builder *builder, t_fvec2 v0, t_fvec2 v1, t_fvec2 v2, t_fvec2 v3, t_fvec2 uv0, t_fvec2 uv1, t_fvec2 uv2, t_fvec2 uv3, t_color color); void finally_draw_uncolored_space_traingle_batch(struct mesh_batch const *batch, t_texture_key texture_key, vertex_buffer buffer); size_t get_text_payload_size(void); bool push_text_payload_to_vertex_buffer_builder(struct font_data const *font_data, vertex_buffer_builder *builder, stbtt_aligned_quad quad); void finally_draw_text(struct font_data const *font_data, size_t len, t_color color, vertex_buffer buffer); #endif