townengine/src/rendering/twn_draw_c.h

251 lines
6.5 KiB
C

#ifndef TWN_DRAW_C_H
#define TWN_DRAW_C_H
#include "twn_textures_c.h"
#include "twn_text_c.h"
#include "twn_util.h"
#include "twn_option.h"
#include <SDL2/SDL.h>
#include <stb_truetype.h>
#ifdef EMSCRIPTEN
#include <GLES2/gl2.h>
#else
#include <glad/glad.h>
#endif
#include <stdbool.h>
extern Matrix4 camera_projection_matrix;
extern Matrix4 camera_look_at_matrix;
#define QUAD_ELEMENT_BUFFER_LENGTH (65536 / 6)
#define CIRCLE_VERTICES_MAX 2048
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);
/* 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);
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);
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);
/* 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 const *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);
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 use_space_pipeline(void);
void use_2d_pipeline(void);
void use_texture_mode(TextureMode mode);
void finally_render_quads(Primitive2D const primitives[],
struct QuadBatch batch,
VertexBuffer buffer);
size_t get_quad_payload_size(struct QuadBatch batch);
bool push_quad_payload_to_vertex_buffer_builder(struct QuadBatch 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);
void start_render_frame(void);
void end_render_frame(void);
#endif