#ifndef TWN_DRAW_C_H #define TWN_DRAW_C_H /* TODO: structure more categorically */ #include "twn_textures_c.h" #include "twn_types_c.h" #include "twn_text_c.h" #include "twn_option.h" #include "twn_deferred_commands.h" #include #include #include extern Matrix4 camera_projection_matrix; extern Matrix4 camera_look_at_matrix; extern double depth_range_low, depth_range_high; #define QUAD_ELEMENT_BUFFER_LENGTH (65536 / 6) #define CIRCLE_VERTICES_MAX 2048 /* TODO: limit to only most necessary */ enum { TWN_FLOAT, TWN_INT, TWN_SHORT, TWN_UNSIGNED_SHORT, TWN_UNSIGNED_INT, TWN_BYTE, TWN_UNSIGNED_BYTE, }; typedef uint32_t VertexBuffer; typedef struct VertexBufferBuilder { size_t size; void *base; } VertexBufferBuilder; typedef struct SpritePrimitive { Rect rect; Color color; float rotation; TextureKey texture_key; m_option_list( Rect, texture_region ) bool flip_x; bool flip_y; bool repeat; } SpritePrimitive; typedef struct RectPrimitive { Rect rect; Color color; } RectPrimitive; typedef struct CirclePrimitive { Vec2 position; float radius; Color color; } CirclePrimitive; typedef struct TextPrimitive { Vec2 position; char *text; const char *font; Color color; int height_px; } TextPrimitive; typedef enum Primitive2DType { PRIMITIVE_2D_SPRITE, PRIMITIVE_2D_RECT, PRIMITIVE_2D_CIRCLE, PRIMITIVE_2D_TEXT, } Primitive2DType; typedef struct Primitive2D { Primitive2DType type; /* TODO: separate to structure of arrays for more efficient memory usage? */ union { SpritePrimitive sprite; RectPrimitive rect; CirclePrimitive circle; TextPrimitive text; }; } Primitive2D; /* union for in-place recalculation of texture coordinates */ /* needs to be later resolved in texture atlas */ typedef struct UncoloredSpaceTriangle { Vec3 v0; Vec2 uv0; /* in pixels */ Vec3 v1; Vec2 uv1; /* in pixels */ Vec3 v2; Vec2 uv2; /* in pixels */ } UncoloredSpaceTriangle; typedef struct SpaceBillboard { Vec3 position; Vec2 size; Color color; // TextureKey texture; /* is assumed from other places */ bool cylindrical; } SpaceBillboard; /* batch of primitives with overlapping properties */ typedef struct MeshBatch { uint8_t *primitives; /* note: interpretation of it is arbitrary */ } MeshBatch; /* TODO: use atlas id instead */ typedef struct MeshBatchItem { TextureKey key; struct MeshBatch value; } MeshBatchItem; typedef struct TextCache { struct FontData **data; } TextCache; /* TODO: try using the fact we utilize edge coloring and step virtual color attributes to bogus points */ /* this is only doable is we take out color attribute to separate array or a portion of it */ /* interleaved vertex array data */ typedef struct ElementIndexedQuad { /* upper-left */ Vec2 v0; Vec2 uv0; Color c0; /* bottom-left */ Vec2 v1; Vec2 uv1; Color c1; /* bottom-right */ Vec2 v2; Vec2 uv2; Color c2; /* upper-right */ Vec2 v3; Vec2 uv3; Color c3; } ElementIndexedQuad; typedef struct ElementIndexedQuadWithoutColor { /* upper-left */ Vec2 v0; Vec2 uv0; /* bottom-left */ Vec2 v1; Vec2 uv1; /* bottom-right */ Vec2 v2; Vec2 uv2; /* upper-right */ Vec2 v3; Vec2 uv3; } ElementIndexedQuadWithoutColor; typedef struct ElementIndexedQuadWithoutTexture { /* upper-left */ Vec2 v0; Color c0; /* bottom-left */ Vec2 v1; Color c1; /* bottom-right */ Vec2 v2; Color c2; /* upper-right */ Vec2 v3; Color c3; } ElementIndexedQuadWithoutTexture; typedef struct ElementIndexedQuadWithoutColorWithoutTexture { /* upper-left */ Vec2 v0; /* bottom-left */ Vec2 v1; /* bottom-right */ Vec2 v2; /* upper-right */ Vec2 v3; } ElementIndexedQuadWithoutColorWithoutTexture; /* TODO: no color variant */ typedef struct ElementIndexedBillboard { /* upper-left */ Vec3 v0; Vec2 uv0; Color c0; /* bottom-left */ Vec3 v1; Vec2 uv1; Color c1; /* bottom-right */ Vec3 v2; Vec2 uv2; Color c2; /* upper-right */ Vec3 v3; Vec2 uv3; Color c3; } ElementIndexedBillboard; bool render_init(void); /* renders the background, then the primitives in all render queues */ void render(void); /* clears all render queues */ void render_queue_clear(void); /* fills two existing arrays with the geometry data of a circle */ /* the size of indices must be at least 3 times the number of vertices */ void create_circle_geometry(Vec2 position, float radius, size_t num_vertices, Vec2 vertices[]); struct QuadBatch { size_t size; /* how many primitives are in current batch */ TextureKey texture_key; TextureMode mode; /* how color should be applied */ bool constant_colored; /* whether colored batch is uniformly colored */ bool repeat; /* whether repeat is needed */ bool textured; } collect_quad_batch(const Primitive2D primitives[], size_t len); void render_quad_batch(const Primitive2D primitives[], struct QuadBatch batch); struct QuadBatch collect_sprite_batch(const Primitive2D primitives[], size_t len); struct QuadBatch collect_rect_batch(const Primitive2D primitives[], size_t len); void render_sprite_batch(const Primitive2D primitives[], struct QuadBatch batch); void render_rect_batch(const Primitive2D primitives[], struct QuadBatch batch); /* text */ void render_text(const TextPrimitive *text); void text_cache_init(TextCache *cache); void text_cache_deinit(TextCache *cache); void text_cache_reset_arena(TextCache *cache); /* vertex buffer */ VertexBuffer create_vertex_buffer(void); void restart_scratch_vertex_arrays(void); VertexBuffer get_scratch_vertex_array(void); void delete_vertex_buffer(VertexBuffer buffer); void specify_vertex_buffer(VertexBuffer buffer, void const *data, size_t bytes); /* uses present in 1.5 buffer mapping feature */ VertexBufferBuilder build_vertex_buffer(VertexBuffer buffer, size_t bytes); void finish_vertex_builder(VertexBufferBuilder *builder); /* state */ void setup_viewport(int x, int y, int width, int height); void clear_draw_buffer(void); void finally_clear_draw_buffer(DeferredCommandClear command); void swap_buffers(void); void set_depth_range(double low, double high); VertexBuffer get_quad_element_buffer(void); VertexBuffer get_circle_element_buffer(void); void render_circle(const CirclePrimitive *circle); void render_rectangle(const RectPrimitive *rectangle); void finally_render_quads(Primitive2D const primitives[], struct QuadBatch batch, VertexBuffer buffer); size_t get_quad_payload_size(struct QuadBatch batch); void push_quad_payload_to_vertex_buffer_builder(struct QuadBatch batch, size_t index, VertexBufferBuilder *builder, Vec2 v0, Vec2 v1, Vec2 v2, Vec2 v3, Vec2 uv0, Vec2 uv1, Vec2 uv2, Vec2 uv3, Color color); void finally_draw_uncolored_space_traingle_batch(MeshBatch const *batch, TextureKey texture_key); void finally_draw_billboard_batch(MeshBatch const *batch, TextureKey texture_key); void finally_draw_text(FontData const *font_data, size_t len, Color color, VertexBuffer buffer); void render_skybox(void); void finally_render_skybox(DeferredCommandDrawSkybox); void start_render_frame(void); void end_render_frame(void); void finally_draw_command(DeferredCommandDraw command); void issue_deferred_draw_commands(void); #endif