339 lines
8.2 KiB
C
339 lines
8.2 KiB
C
#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 <SDL2/SDL.h>
|
|
#include <stb_truetype.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
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 LinePrimitive {
|
|
Vec2 start;
|
|
Vec2 finish;
|
|
float thickness;
|
|
Color color;
|
|
} LinePrimitive;
|
|
|
|
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_LINE,
|
|
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;
|
|
LinePrimitive line;
|
|
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_line(const LinePrimitive *line);
|
|
|
|
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
|