dis_
This commit is contained in:
parent
714c5d08bf
commit
fc03951086
@ -8,51 +8,112 @@
|
||||
#pragma once
|
||||
|
||||
#include "drawglx.h"
|
||||
#include "programs.h"
|
||||
|
||||
#include "vector.h"
|
||||
#include "vec234.h"
|
||||
#include "mat4.h"
|
||||
|
||||
enum
|
||||
{
|
||||
PROGRAM_TRIANGLES_PLAIN,
|
||||
PROGRAM_TRIANGLES_TEXTURED,
|
||||
PROGRAM_FREETYPE,
|
||||
PROGRAM_COUNT
|
||||
};
|
||||
|
||||
typedef void(*program_callback_fn)(struct draw_cmd *);
|
||||
typedef void(*program_callback_empty_fn)();
|
||||
|
||||
struct program_t
|
||||
{
|
||||
vertex_buffer_t *vertex;
|
||||
GLuint shader;
|
||||
|
||||
program_callback_empty_fn init;
|
||||
program_callback_empty_fn load;
|
||||
program_callback_fn render;
|
||||
program_callback_empty_fn unload;
|
||||
program_callback_empty_fn destroy;
|
||||
};
|
||||
|
||||
void
|
||||
program_init_inplace(struct program_t *program, const char *vertex_format, const char *shader_frag, const char *shader_vert, program_callback_empty_fn init, program_callback_empty_fn load, program_callback_fn render, program_callback_empty_fn unload, program_callback_empty_fn destroy);
|
||||
|
||||
struct program_t programs[PROGRAM_COUNT];
|
||||
|
||||
int
|
||||
drawglx_internal_init();
|
||||
|
||||
enum
|
||||
{
|
||||
DI_INVALID_INSTRUCTION,
|
||||
DI_SWITCH_PROGRAM,
|
||||
DI_PUSH_VERTICES,
|
||||
DI_PUSH_INDICES,
|
||||
DI_PROGRAM_SWITCH_TEXTURE,
|
||||
DI_PROGRAM_SWITCH_FONT,
|
||||
DI_TERMINATE
|
||||
};
|
||||
|
||||
struct draw_instruction_t
|
||||
{
|
||||
int type;
|
||||
union
|
||||
{
|
||||
/* DI_SWITCH_PROGRAM */
|
||||
int program;
|
||||
/* DI_PUSH_VERTICES / DI_PUSH_INDICES */
|
||||
size_t count;
|
||||
/* DI_PROGRAM_SWITCH_TEXTURE */
|
||||
GLuint texture;
|
||||
/* DI_PROGRAM_SWITCH_FONT */
|
||||
texture_font_t *font;
|
||||
};
|
||||
};
|
||||
|
||||
struct draw_instruction_stream_t
|
||||
{
|
||||
void *memory;
|
||||
size_t capacity;
|
||||
size_t write_ptr;
|
||||
size_t read_ptr;
|
||||
size_t last_draw_instruction_offset;
|
||||
};
|
||||
|
||||
struct draw_instruction_stream_t dstream;
|
||||
|
||||
void
|
||||
dis_init();
|
||||
|
||||
void
|
||||
dis_destroy();
|
||||
|
||||
void
|
||||
dis_reset();
|
||||
|
||||
void
|
||||
dis_reserve(size_t bytes);
|
||||
|
||||
struct draw_instruction_t*
|
||||
dis_last_pushed_instruction();
|
||||
|
||||
void
|
||||
dis_push_data(size_t bytes, void *data);
|
||||
|
||||
void
|
||||
dis_push_instruction(struct draw_instruction_t instr);
|
||||
|
||||
size_t
|
||||
dis_fetch_data(size_t bytes, void *data);
|
||||
|
||||
void
|
||||
dis_switch_program(int program);
|
||||
|
||||
void
|
||||
dis_push_vertices(size_t count, size_t vertex_size, void *vertex_data);
|
||||
|
||||
void
|
||||
dis_push_indices(size_t count, GLuint *index_data);
|
||||
|
||||
void
|
||||
dis_program_switch_texture(GLuint texture);
|
||||
|
||||
void
|
||||
dis_program_switch_font(texture_font_t *font);
|
||||
|
||||
void
|
||||
dis_finish();
|
||||
|
||||
struct draw_instruction_t*
|
||||
dis_fetch_instruction();
|
||||
|
||||
struct draw_cmd
|
||||
{
|
||||
vector_t *vertices;
|
||||
vector_t *indices;
|
||||
|
||||
int program;
|
||||
GLuint texture;
|
||||
struct program_data_t data;
|
||||
};
|
||||
|
||||
struct draw_cmd*
|
||||
draw_cmd_new();
|
||||
draw_cmd_new(int program);
|
||||
|
||||
void
|
||||
draw_cmd_delete(struct draw_cmd *cmd);
|
||||
|
||||
struct draw_state
|
||||
{
|
||||
@ -67,28 +128,48 @@ struct draw_state
|
||||
struct size_t current_command;
|
||||
};
|
||||
|
||||
struct draw_state drawstate;
|
||||
struct draw_state ds;
|
||||
|
||||
void
|
||||
draw_state_init();
|
||||
ds_init();
|
||||
|
||||
void
|
||||
draw_state_next_command();
|
||||
ds_destroy();
|
||||
|
||||
void
|
||||
draw_state_free();
|
||||
ds_alloc_next_command(int program);
|
||||
|
||||
void
|
||||
draw_state_clear();
|
||||
ds_next_frame();
|
||||
|
||||
void
|
||||
draw_state_render();
|
||||
ds_render();
|
||||
|
||||
void
|
||||
draw_set_texture(GLuint texture);
|
||||
ds_prepare_command(int program);
|
||||
|
||||
/* Primitive Internal Drawing API */
|
||||
|
||||
void
|
||||
draw_line(float x, float y, float x2, float y2);
|
||||
draw_line(vec2 xy, vec2 delta, vec4 color);
|
||||
|
||||
void
|
||||
draw_rect(float x, float y, float w, float h);
|
||||
draw_rect(vec2 xy, vec2 hw, vec4 color);
|
||||
|
||||
void
|
||||
draw_rect_outline(vec2 xy, vec2 hw, vec4 color);
|
||||
|
||||
void
|
||||
draw_rect_textured(vec2 xy, vec2 hw, vec4 color, int texture, vec2 uv, vec2 st);
|
||||
|
||||
void
|
||||
draw_string(vec2 xy, const char *string, texture_font_t *font, vec4 color);
|
||||
|
||||
void
|
||||
draw_string_outline(vec2 xy, const char *string, texture_font_t *font, vec4 color);
|
||||
|
||||
void
|
||||
draw_string_with_outline(vec2 xy, const char *string, texture_font_t *font, vec4 color, vec4 outline_color);
|
||||
|
||||
void
|
||||
get_string_size(const char *string, texture_font_t *font, vec2 *out);
|
||||
|
@ -7,27 +7,81 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "freetype-gl.h"
|
||||
|
||||
struct draw_cmd;
|
||||
|
||||
#define PROGRAM_INIT(name) program_##name##_init
|
||||
#define PROGRAM_LOAD(name) program_##name##_load
|
||||
#define PROGRAM_RENDER(name) program_##name##_render
|
||||
#define PROGRAM_UNLOAD(name) program_##name##_unload
|
||||
#define PROGRAM_DESTROY(name) program_##name##_destroy
|
||||
#define PROGRAM_CHECK(name) program_##name##_check
|
||||
|
||||
#define DECL_PROGRAM_INIT(name) void program_##name##_init()
|
||||
#define DECL_PROGRAM_LOAD(name) void program_##name##_load()
|
||||
#define DECL_PROGRAM_RENDER(name) void program_##name##_render(struct draw_cmd *cmd)
|
||||
#define DECL_PROGRAM_UNLOAD(name) void program_##name##_unload()
|
||||
#define DECL_PROGRAM_DESTROY(name) void program_##name##_destroy()
|
||||
#define DECL_PROGRAM_CHECK(name) int program_##name##_check(struct draw_cmd *cmd, void *data)
|
||||
|
||||
#define DECL_PROGRAM(name) \
|
||||
DECL_PROGRAM_INIT(name); \
|
||||
DECL_PROGRAM_LOAD(name); \
|
||||
DECL_PROGRAM_RENDER(name); \
|
||||
DECL_PROGRAM_UNLOAD(name); \
|
||||
DECL_PROGRAM_DESTROY(name)
|
||||
DECL_PROGRAM_DESTROY(name); \
|
||||
DECL_PROGRAM_CHECK(name)
|
||||
|
||||
enum
|
||||
{
|
||||
PROGRAM_TRIANGLES_PLAIN,
|
||||
PROGRAM_TRIANGLES_TEXTURED,
|
||||
PROGRAM_FREETYPE,
|
||||
PROGRAM_COUNT
|
||||
};
|
||||
|
||||
typedef void(*program_callback_fn)(struct draw_cmd *);
|
||||
typedef void(*program_callback_empty_fn)();
|
||||
typedef int(*program_callback_check_command_fn)(struct draw_cmd *cmd, void *data);
|
||||
|
||||
struct program_t
|
||||
{
|
||||
vertex_buffer_t *vertex;
|
||||
GLuint shader;
|
||||
|
||||
program_callback_empty_fn init;
|
||||
program_callback_empty_fn load;
|
||||
program_callback_fn render;
|
||||
program_callback_empty_fn unload;
|
||||
program_callback_empty_fn destroy;
|
||||
program_callback_check_command_fn check;
|
||||
};
|
||||
|
||||
void
|
||||
program_init_inplace(struct program_t *program, const char *vertex_format, const char *shader_frag, const char *shader_vert, program_callback_empty_fn init, program_callback_empty_fn load, program_callback_fn render, program_callback_empty_fn unload, program_callback_empty_fn destroy, program_callback_check_command_fn check);
|
||||
|
||||
struct program_t programs[PROGRAM_COUNT];
|
||||
|
||||
struct program_data_t
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
int pad;
|
||||
} triangles_plain;
|
||||
struct
|
||||
{
|
||||
GLuint texture;
|
||||
} triangles_textured;
|
||||
struct
|
||||
{
|
||||
texture_font_t *font;
|
||||
} freetype;
|
||||
};
|
||||
};
|
||||
|
||||
DECL_PROGRAM(triangles_plain);
|
||||
DECL_PROGRAM(triangles_textured);
|
||||
DECL_PROGRAM(freetype);
|
||||
|
||||
void program_noop() {};
|
||||
|
37
include/vertex_structs.h
Normal file
37
include/vertex_structs.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* vertex_structs.h
|
||||
*
|
||||
* Created on: Nov 10, 2017
|
||||
* Author: nullifiedcat
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/* Used for drawing primitives */
|
||||
struct vertex_v2fc4f
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
float a;
|
||||
};
|
||||
|
||||
/* Used for drawing textured primitives and freetype-gl fonts */
|
||||
struct vertex_v2ft2fc4f
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
|
||||
float s;
|
||||
float t;
|
||||
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
float a;
|
||||
};
|
||||
|
||||
|
@ -7,38 +7,274 @@
|
||||
|
||||
#include "drawglx_internal.h"
|
||||
|
||||
struct draw_state*
|
||||
draw_state_init(size_t vertex_size)
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
drawglx_internal_init()
|
||||
{
|
||||
struct draw_state *result = calloc(1, sizeof(struct draw_state));
|
||||
result->commands = vector_new(sizeof(struct draw_cmd));
|
||||
result->current_command = -1;
|
||||
return result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
draw_state_next_command(struct draw_state *state)
|
||||
dis_init()
|
||||
{
|
||||
|
||||
dstream.capacity = 128;
|
||||
dstream.memory = malloc(dstream.capacity);
|
||||
struct draw_instruction_t *instr = dstream.memory;
|
||||
instr->type = DI_INVALID_INSTRUCTION;
|
||||
}
|
||||
|
||||
void
|
||||
draw_state_free(struct draw_state *state)
|
||||
dis_destroy()
|
||||
{
|
||||
|
||||
free(dstream.memory);
|
||||
}
|
||||
|
||||
void
|
||||
draw_state_clear(struct draw_state *state)
|
||||
dis_reset()
|
||||
{
|
||||
for (int i = 0; i < vector_size(state->commands); ++i)
|
||||
dstream.write_ptr = 0;
|
||||
dstream.read_ptr = 0;
|
||||
}
|
||||
|
||||
void
|
||||
dis_reserve(size_t bytes)
|
||||
{
|
||||
while (dstream.write_ptr + bytes > dstream.capacity)
|
||||
{
|
||||
struct draw_cmd *current = vector_get(state->commands, i);
|
||||
dstream.capacity *= 2;
|
||||
dstream.memory = realloc(dstream.memory, dstream.capacity);
|
||||
}
|
||||
}
|
||||
|
||||
struct draw_instruction_t*
|
||||
dis_last_pushed_instruction()
|
||||
{
|
||||
if (dstream.write_ptr == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return (struct draw_instruction_t *)(dstream.memory + dstream.last_draw_instruction_offset);
|
||||
}
|
||||
|
||||
void
|
||||
dis_push_data(size_t bytes, void *data)
|
||||
{
|
||||
dis_reserve(bytes);
|
||||
memcpy(dstream.memory + dstream.write_ptr, data, bytes);
|
||||
dstream.write_ptr += bytes;
|
||||
}
|
||||
|
||||
void
|
||||
dis_push_instruction(struct draw_instruction_t instr)
|
||||
{
|
||||
dstream.last_draw_instruction_offset = dstream.write_ptr;
|
||||
dis_push_data(sizeof(struct draw_instruction_t), &instr);
|
||||
}
|
||||
|
||||
size_t
|
||||
dis_fetch_data(size_t bytes, void *data)
|
||||
{
|
||||
size_t read_count = bytes;
|
||||
if (dstream.read_ptr + bytes < dstream.capacity)
|
||||
read_count = dstream.capacity - dstream.read_ptr;
|
||||
memcpy(data, dstream.memory + dstream.read_ptr, bytes);
|
||||
dstream.read_ptr += bytes;
|
||||
return read_count;
|
||||
}
|
||||
|
||||
void
|
||||
dis_switch_program(int program)
|
||||
{
|
||||
struct draw_instruction_t *last = dis_last_pushed_instruction();
|
||||
|
||||
if (last && last->type == DI_SWITCH_PROGRAM)
|
||||
{
|
||||
last->program = program;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct draw_instruction_t instr;
|
||||
|
||||
instr.type = DI_SWITCH_PROGRAM;
|
||||
instr.program = program;
|
||||
dis_push_instruction(instr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
draw_state_render(struct draw_state *state)
|
||||
dis_push_vertices(size_t count, size_t vertex_size, void *vertex_data)
|
||||
{
|
||||
struct draw_instruction_t *last = dis_last_pushed_instruction();
|
||||
|
||||
if (last && (last->type == DI_PUSH_VERTICES))
|
||||
{
|
||||
dis_push_data(count * vertex_size, vertex_data);
|
||||
last->count += count;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct draw_instruction_t instr;
|
||||
|
||||
instr.type = DI_PUSH_VERTICES;
|
||||
instr.count = count;
|
||||
dis_push_instruction(instr);
|
||||
dis_push_data(count * vertex_size, vertex_data);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dis_push_indices(size_t count, GLuint *index_data)
|
||||
{
|
||||
struct draw_instruction_t *last = dis_last_pushed_instruction();
|
||||
|
||||
if (last && (last->type == DI_PUSH_INDICES))
|
||||
{
|
||||
dis_push_data(count * sizeof(GLuint), index_data);
|
||||
last->count += count;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct draw_instruction_t instr;
|
||||
|
||||
instr.type = DI_PUSH_INDICES;
|
||||
instr.count = count;
|
||||
dis_push_instruction(instr);
|
||||
dis_push_data(count * sizeof(GLuint), index_data);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dis_program_switch_texture(GLuint texture)
|
||||
{
|
||||
struct draw_instruction_t *last = dis_last_pushed_instruction();
|
||||
|
||||
if (last && last->type == DI_PROGRAM_SWITCH_TEXTURE)
|
||||
{
|
||||
last->texture = texture;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct draw_instruction_t instr;
|
||||
|
||||
instr.type = DI_PROGRAM_SWITCH_TEXTURE;
|
||||
instr.texture = texture;
|
||||
dis_push_instruction(instr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dis_program_switch_font(texture_font_t *font)
|
||||
{
|
||||
struct draw_instruction_t *last = dis_last_pushed_instruction();
|
||||
|
||||
if (last && last->type == DI_PROGRAM_SWITCH_FONT)
|
||||
{
|
||||
last->font = font;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct draw_instruction_t instr;
|
||||
|
||||
instr.type = DI_PROGRAM_SWITCH_FONT;
|
||||
instr.font = font;
|
||||
dis_push_instruction(instr);
|
||||
}
|
||||
}
|
||||
|
||||
struct draw_instruction_t terminate = { .type = DI_TERMINATE };
|
||||
|
||||
void
|
||||
dis_finish()
|
||||
{
|
||||
dis_push_instruction(terminate);
|
||||
}
|
||||
|
||||
struct draw_instruction_t*
|
||||
dis_fetch_instruction()
|
||||
{
|
||||
if (dstream.read_ptr + sizeof(struct draw_instruction_t) > dstream.capacity)
|
||||
return NULL;
|
||||
struct draw_instruction_t *result;
|
||||
result = (struct draw_instruction_t *)(dstream.memory + dstream.read_ptr);
|
||||
dstream.read_ptr += sizeof(struct draw_instruction_t);
|
||||
return result;
|
||||
}
|
||||
|
||||
struct draw_cmd*
|
||||
draw_cmd_new(int program)
|
||||
{
|
||||
struct draw_cmd *result = calloc(1, sizeof(struct draw_cmd));
|
||||
result->program = program;
|
||||
result->vertices = vector_new(programs[program]->vertex->vertices->item_size);
|
||||
result->indices = vector_new(programs[program]->vertex->indices->item_size);
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
draw_cmd_delete(struct draw_cmd *cmd)
|
||||
{
|
||||
vector_delete(cmd->vertices);
|
||||
vector_delete(cmd->indices);
|
||||
free(cmd);
|
||||
}
|
||||
|
||||
void
|
||||
ds_init()
|
||||
{
|
||||
memset(&ds, 0, sizeof(struct draw_state));
|
||||
ds.commands = vector_new(sizeof(struct draw_cmd));
|
||||
vector_push_back(ds.commands, calloc(1, sizeof(struct draw_cmd)));
|
||||
ds.current_command = 0;
|
||||
}
|
||||
|
||||
void
|
||||
ds_destroy()
|
||||
{
|
||||
for (int i = 0; i < ds.commands->size; ++i)
|
||||
{
|
||||
struct draw_cmd *cmd = vector_get(ds.commands, i);
|
||||
draw_cmd_delete(cmd);
|
||||
}
|
||||
vector_delete(ds.commands);
|
||||
}
|
||||
|
||||
void
|
||||
ds_alloc_next_command(int program)
|
||||
{
|
||||
struct draw_cmd *result = calloc(1, sizeof(struct draw_cmd));
|
||||
result->program = program;
|
||||
vector_push_back(ds.commands, result);
|
||||
ds.current_command++;
|
||||
}
|
||||
|
||||
void
|
||||
ds_next_frame()
|
||||
{
|
||||
for (int i = 0; i < ds.commands->size; ++i)
|
||||
{
|
||||
struct draw_cmd *cmd = vector_get(ds.commands, i);
|
||||
draw_cmd_delete(cmd);
|
||||
}
|
||||
vector_resize(ds.commands, 1);
|
||||
memset(vector_get(ds.commands, 0), 0, sizeof(struct draw_cmd));
|
||||
ds.current_command = 0;
|
||||
}
|
||||
|
||||
void
|
||||
ds_render()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ds_render()
|
||||
{
|
||||
for (int i = 0; i < vector_size(state->commands); ++i)
|
||||
{
|
||||
@ -69,19 +305,70 @@ draw_state_render(struct draw_state *state)
|
||||
}
|
||||
|
||||
void
|
||||
draw_set_texture(struct draw_state *state, GLuint texture)
|
||||
ds_prepare_command(int program)
|
||||
{
|
||||
int should_alloc_command = 0;
|
||||
struct draw_cmd *current = vector_get(ds.commands, ds.current_command);
|
||||
|
||||
if (current == NULL)
|
||||
should_alloc_command = 1;
|
||||
else if (program != current->program)
|
||||
should_alloc_command = 1;
|
||||
else if (programs[program].check && !programs[program].check(current))
|
||||
should_alloc_command = 1;
|
||||
|
||||
if (should_alloc_command)
|
||||
{
|
||||
ds_alloc_next_command();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
draw_line(vec2 xy, vec2 delta, vec4 color)
|
||||
{
|
||||
ds_prepare_command(PROGRAM_TRIANGLES_PLAIN);
|
||||
vertex_buffer_delete();
|
||||
}
|
||||
|
||||
void
|
||||
draw_rect(vec2 xy, vec2 hw, vec4 color)
|
||||
{
|
||||
ds_prepare_command(PROGRAM_TRIANGLES_PLAIN);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
draw_line(struct draw_state *state, float x, float y, float x2, float y2)
|
||||
draw_rect_outline(vec2 xy, vec2 hw, vec4 color)
|
||||
{
|
||||
|
||||
ds_prepare_command(PROGRAM_TRIANGLES_PLAIN);
|
||||
}
|
||||
|
||||
void
|
||||
draw_rect(struct draw_state *state, float x, float y, float w, float h)
|
||||
draw_rect_textured(vec2 xy, vec2 hw, vec4 color, int texture, vec2 uv, vec2 st)
|
||||
{
|
||||
ds_prepare_command(PROGRAM_TRIANGLES_TEXTURED);
|
||||
}
|
||||
|
||||
void
|
||||
draw_string(vec2 xy, const char *string, texture_font_t *font, vec4 color)
|
||||
{
|
||||
ds_prepare_command(PROGRAM_FREETYPE);
|
||||
}
|
||||
|
||||
void
|
||||
draw_string_outline(vec2 xy, const char *string, texture_font_t *font, vec4 color)
|
||||
{
|
||||
ds_prepare_command(PROGRAM_FREETYPE);
|
||||
}
|
||||
|
||||
void
|
||||
draw_string_with_outline(vec2 xy, const char *string, texture_font_t *font, vec4 color, vec4 outline_color)
|
||||
{
|
||||
ds_prepare_command(PROGRAM_FREETYPE);
|
||||
}
|
||||
|
||||
void
|
||||
get_string_size(const char *string, texture_font_t *font, vec2 *out)
|
||||
{
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user