#ifndef TWN_RENDERING_C_H #define TWN_RENDERING_C_H #include "twn_textures_c.h" #include "twn_text_c.h" #include "twn_util.h" #include "twn_option.h" #include #include #ifdef EMSCRIPTEN #include #else #include #endif #include extern Matrix4 camera_projection_matrix; extern Matrix4 camera_look_at_matrix; #define QUAD_ELEMENT_BUFFER_LENGTH (65536 / 6) typedef GLuint VertexBuffer; typedef struct VertexBufferBuilder { size_t bytes_left; void *mapping; } VertexBufferBuilder; typedef struct SpritePrimitive { Rect rect; Color color; float rotation; TextureKey texture_key; bool flip_x; bool flip_y; bool repeat; m_option_list( Rect, texture_region ) } SpritePrimitive; typedef struct RectPrimitive { Rect rect; Color color; } RectPrimitive; typedef struct CirclePrimitive { float radius; Color color; Vec2 position; } CirclePrimitive; typedef struct TextPrimitive { Color color; Vec2 position; char *text; const char *font; 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; union { SpritePrimitive sprite; RectPrimitive rect; CirclePrimitive circle; TextPrimitive text; }; } Primitive2D; /* union for in-place recalculation of texture coordinates */ union UncoloredSpaceTriangle { /* pending for sending, uvs are not final as texture atlases could update */ struct UncoloredSpaceTrianglePrimitive { Vec3 v0; Vec2 uv0; /* in pixels */ Vec3 v1; Vec2 uv1; /* in pixels */ Vec3 v2; Vec2 uv2; /* in pixels */ } primitive; /* TODO: have it packed? */ /* structure that is passed in opengl vertex array */ struct UncoloredSpaceTrianglePayload { Vec3 v0; Vec2 uv0; Vec3 v1; Vec2 uv1; Vec3 v2; Vec2 uv2; } payload; }; /* batch of primitives with overlapping properties */ typedef struct MeshBatch { uint8_t *primitives; } MeshBatch; typedef struct MeshBatchItem { TextureKey key; struct MeshBatch value; } MeshBatchItem; typedef struct TextCache { struct FontData **data; } TextCache; /* 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(Vec2 position, Color color, float radius, size_t num_vertices, SDL_Vertex **vertices_out, int **indices_out); struct SpriteBatch { size_t size; /* how many primitives are in current batch */ TextureMode mode; bool constant_colored; /* whether colored batch is uniformly colored */ bool repeat; /* whether repeat is needed */ } collect_sprite_batch(const Primitive2D primitives[], size_t len); void render_sprites(const Primitive2D primitives[], const struct SpriteBatch batch); void draw_uncolored_space_traingle_batch(MeshBatch *batch, TextureKey texture_key); /* 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 delete_vertex_buffer(VertexBuffer buffer); void specify_vertex_buffer(VertexBuffer buffer, void *data, size_t bytes); /* uses present in 1.5 buffer mapping feature */ VertexBufferBuilder build_vertex_buffer(VertexBuffer 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(VertexBufferBuilder *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 CirclePrimitive *circle); void render_rectangle(const RectPrimitive *rectangle); void use_space_pipeline(void); void use_2d_pipeline(void); void use_texture_mode(TextureMode mode); void finally_render_sprites(Primitive2D const primitives[], struct SpriteBatch batch, VertexBuffer buffer); size_t get_sprite_payload_size(struct SpriteBatch batch); bool push_sprite_payload_to_vertex_buffer_builder(struct SpriteBatch batch, 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, VertexBuffer buffer); size_t get_text_payload_size(void); bool push_text_payload_to_vertex_buffer_builder(FontData const *font_data, VertexBufferBuilder *builder, stbtt_aligned_quad quad); void finally_draw_text(FontData const *font_data, size_t len, Color color, VertexBuffer buffer); void render_skybox(void); void finally_render_skybox(char *paths_in_use); void apply_fog(void); void finally_apply_fog(float start, float end, float density, Color color); void pop_fog(void); void finally_pop_fog(void); #endif