diff --git a/Makefile b/Makefile index 15088b0..f7ad5bb 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC=$(shell sh -c "which gcc-7 || which gcc") CFLAGS=-O3 -Wall -fPIC -fmessage-length=0 -D_GNU_SOURCE=1 -DFREETYPE_GL_USE_VAO=1 -g3 -ggdb -Iinclude -isystemftgl -isystem/usr/local/include/freetype2 -isystem/usr/include/freetype2 -LDFLAGS=-shared +LDFLAGS=-shared -Wl,--no-undefined LDLIBS=-lm -lX11 -lXext -lrt -lpthread -lXfixes -lGL -lfreetype -lGLEW -lpng SRC_DIR=src BIN32_DIR=bin32 diff --git a/bin32/liboverlay.so b/bin32/liboverlay.so index 39605c8..e2a007a 100755 Binary files a/bin32/liboverlay.so and b/bin32/liboverlay.so differ diff --git a/bin64/liboverlay.so b/bin64/liboverlay.so index 19dce4d..58d2966 100755 Binary files a/bin64/liboverlay.so and b/bin64/liboverlay.so differ diff --git a/include/drawglx_internal.h b/include/drawglx_internal.h index a8f37d9..06d1484 100644 --- a/include/drawglx_internal.h +++ b/include/drawglx_internal.h @@ -9,7 +9,6 @@ #include "drawglx.h" #include "fontapi_internal.h" -#include "programs.h" #include "textureapi_internal.h" #include "vector.h" @@ -19,111 +18,14 @@ 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_TEXTUREAPI_BIND_TEXTURE, - 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 */ - xoverlay_font_handle_t font; - /* */ - xoverlay_texture_handle_t thandle; - }; -}; - -struct draw_instruction_stream_t -{ - void *memory; - size_t capacity; - size_t write_ptr; - size_t read_ptr; - size_t last_draw_instruction_offset; - GLuint next_index; -}; - -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_read_data(size_t bytes); - -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_textureapi_switch_texture(xoverlay_texture_handle_t texture); - -void -dis_program_switch_font(xoverlay_font_handle_t font); - -void -dis_finish(); - -struct draw_instruction_t* -dis_fetch_instruction(); - struct draw_state { mat4 model, view, projection; - int program; int dirty; - GLuint texture; + GLuint texture; xoverlay_font_handle_t font; - xoverlay_texture_handle_t thandle; - - GLuint shader; }; struct draw_state ds; @@ -137,9 +39,6 @@ ds_destroy(); void ds_mark_dirty(); -void -ds_prepare_program(int program); - void ds_render_if_needed(); @@ -149,27 +48,5 @@ ds_pre_render(); void ds_post_render(); -void -ds_render_next_frame(); - -/* To be called by draw functions */ - -void -ds_prepare_texture_handle(xoverlay_texture_handle_t handle); - -void -ds_prepare_texture(GLuint texture); - -void -ds_prepare_font(xoverlay_font_handle_t font); - -/* To be called from programs */ - void ds_bind_texture(GLuint texture); - -void -ds_use_shader(GLuint shader); - -void -ds_use_font(xoverlay_font_handle_t font); diff --git a/include/log.h b/include/log.h index 7bc2ba5..32cefc3 100644 --- a/include/log.h +++ b/include/log.h @@ -7,7 +7,7 @@ #pragma once -#define DEBUG 0 +#define DEBUG 1 #if DEBUG diff --git a/include/program.h b/include/program.h index 767032e..e7dac7b 100644 --- a/include/program.h +++ b/include/program.h @@ -2,8 +2,16 @@ #include +enum +{ + DRAW_MODE_PLAIN = 1, + DRAW_MODE_TEXTURED, + DRAW_MODE_FREETYPE +}; + struct program_t { + char shader_active; unsigned shader; vertex_buffer_t *buffer; }; @@ -14,4 +22,10 @@ void program_init(); void -program_draw(); \ No newline at end of file +program_draw(); + +void +program_reset(); + +unsigned +program_next_index(); diff --git a/include/programs.h b/include/programs.h deleted file mode 100644 index 2b479bc..0000000 --- a/include/programs.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * programs.h - * - * Created on: Nov 10, 2017 - * Author: nullifiedcat - */ - -#pragma once - -#include "freetype-gl.h" -#include "vertex-buffer.h" -#include "fontapi.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 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() -#define DECL_PROGRAM_UNLOAD(name) void program_##name##_unload() -#define DECL_PROGRAM_DESTROY(name) void program_##name##_destroy() - -#define DECL_PROGRAM(name) \ - DECL_PROGRAM_INIT(name); \ - DECL_PROGRAM_LOAD(name); \ - DECL_PROGRAM_RENDER(name); \ - DECL_PROGRAM_UNLOAD(name); \ - DECL_PROGRAM_DESTROY(name) - -enum -{ - PROGRAM_TRIANGLES_PLAIN, - PROGRAM_TRIANGLES_TEXTURED, - PROGRAM_FREETYPE, - PROGRAM_COUNT -}; - -typedef void(*program_callback_empty_fn)(); - -struct program_t -{ - vertex_buffer_t *vertex; - size_t vertex_size; - GLuint shader; - - program_callback_empty_fn init; - program_callback_empty_fn load; - program_callback_empty_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_empty_fn render, program_callback_empty_fn unload, program_callback_empty_fn destroy); - -void -program_init_everything(); - -struct program_t programs[PROGRAM_COUNT]; - -DECL_PROGRAM(triangles_plain); -DECL_PROGRAM(triangles_textured); -DECL_PROGRAM(freetype); - -void -program_freetype_switch_font(xoverlay_font_handle_t font); diff --git a/include/vertex_structs.h b/include/vertex_structs.h index 0f81579..68d3b1b 100644 --- a/include/vertex_structs.h +++ b/include/vertex_structs.h @@ -7,19 +7,11 @@ #pragma once -/* Used for drawing primitives */ -struct vertex_v2fc4f +struct vertex_main { - vec2 pos; + vec2 position; + vec2 tex_coords; vec4 color; + unsigned mode; }; -/* Used for drawing textured primitives and freetype-gl fonts */ -struct vertex_v2ft2fc4f -{ - vec2 pos; - vec2 uv; - vec4 color; -}; - - diff --git a/src/drawglx.c b/src/drawglx.c index 88e6e5e..91bc32b 100644 --- a/src/drawglx.c +++ b/src/drawglx.c @@ -7,7 +7,7 @@ #include "drawglx_internal.h" #include "overlay.h" -#include "programs.h" +#include "program.h" #include "vertex_structs.h" #include "log.h" @@ -190,7 +190,7 @@ int xoverlay_glx_create_window() log_write("Initializing DS\n"); ds_init(); - program_init_everything(); + program_init(); return 0; } @@ -217,16 +217,15 @@ xoverlay_draw_line(float x, float y, float dx, float dy, xoverlay_rgba_t color, if (xoverlay_library.mapped == 0 || xoverlay_library.drawing == 0) return; - ds_prepare_program(PROGRAM_TRIANGLES_PLAIN); - x += 0.5f; y += 0.5f; dx -= 0.5f; dy -= 0.5f; - GLuint idx = dstream.next_index; - GLuint indices[6] = { idx, idx + 1, idx + 3, idx + 3, idx +2, idx }; - struct vertex_v2fc4f vertices[4]; + GLuint idx = program_next_index(); + GLuint indices[6] = { idx, idx + 1, idx + 3, idx + 3, idx + 2, idx }; + + struct vertex_main vertices[4]; float nx = -dy; float ny = dx; @@ -243,26 +242,29 @@ xoverlay_draw_line(float x, float y, float dx, float dy, xoverlay_rgba_t color, nx /= length; ny /= length; - vertices[0].pos.x = x - nx; - vertices[0].pos.y = y - ny; + vertices[0].position.x = x - nx; + vertices[0].position.y = y - ny; vertices[0].color = *(vec4*)&color; + vertices[0].mode = DRAW_MODE_PLAIN; - vertices[1].pos.x = x + nx; - vertices[1].pos.y = y + ny; + vertices[1].position.x = x + nx; + vertices[1].position.y = y + ny; vertices[1].color = *(vec4*)&color; + vertices[1].mode = DRAW_MODE_PLAIN; - vertices[2].pos.x = ex - nx; - vertices[2].pos.y = ey - ny; + vertices[2].position.x = ex - nx; + vertices[2].position.y = ey - ny; vertices[2].color = *(vec4*)&color; + vertices[2].mode = DRAW_MODE_PLAIN; - vertices[3].pos.x = ex + nx; - vertices[3].pos.y = ey + ny; + vertices[3].position.x = ex + nx; + vertices[3].position.y = ey + ny; vertices[3].color = *(vec4*)&color; + vertices[3].mode = DRAW_MODE_PLAIN; - dis_push_vertices(4, sizeof(struct vertex_v2fc4f), vertices); - dis_push_indices(6, indices); + vertex_buffer_push_back(program.buffer, vertices, 4, indices, 6); } void @@ -271,35 +273,37 @@ xoverlay_draw_rect(float x, float y, float w, float h, xoverlay_rgba_t color) if (xoverlay_library.mapped == 0 || xoverlay_library.drawing == 0) return; - ds_prepare_program(PROGRAM_TRIANGLES_PLAIN); - GLuint idx = dstream.next_index; + GLuint idx = program_next_index(); x += 0.5f; y += 0.5f; w -= 0.5f; h -= 0.5f; - struct vertex_v2fc4f vertices[4]; + struct vertex_main vertices[4]; GLuint indices[6] = { idx, idx + 1, idx + 2, idx + 2, idx + 3, idx }; - vertices[0].pos.x = x; - vertices[0].pos.y = y; + vertices[0].position.x = x; + vertices[0].position.y = y; vertices[0].color = *(vec4*)&color; + vertices[0].mode = DRAW_MODE_PLAIN; - vertices[1].pos.x = x; - vertices[1].pos.y = y + h; + vertices[1].position.x = x; + vertices[1].position.y = y + h; vertices[1].color = *(vec4*)&color; + vertices[1].mode = DRAW_MODE_PLAIN; - vertices[2].pos.x = x + w; - vertices[2].pos.y = y + h; + vertices[2].position.x = x + w; + vertices[2].position.y = y + h; vertices[2].color = *(vec4*)&color; + vertices[2].mode = DRAW_MODE_PLAIN; - vertices[3].pos.x = x + w; - vertices[3].pos.y = y; + vertices[3].position.x = x + w; + vertices[3].position.y = y; vertices[3].color = *(vec4*)&color; + vertices[3].mode = DRAW_MODE_PLAIN; - dis_push_vertices(4, sizeof(struct vertex_v2fc4f), vertices); - dis_push_indices(6, indices); + vertex_buffer_push_back(program.buffer, vertices, 4, indices, 6); } void @@ -325,17 +329,16 @@ xoverlay_draw_rect_textured(float x, float y, float w, float h, xoverlay_rgba_t if (tex == NULL) return; - ds_prepare_program(PROGRAM_TRIANGLES_TEXTURED); - ds_prepare_texture_handle(texture); + ds_bind_texture(tex->texture_id); x += 0.5f; y += 0.5f; w -= 0.5f; h -= 0.5f; - GLuint idx = dstream.next_index; + GLuint idx = program_next_index(); - struct vertex_v2ft2fc4f vertices[4]; + struct vertex_main vertices[4]; GLuint indices[6] = { idx, idx + 1, idx + 2, idx + 2, idx + 3, idx }; float s0 = tx / tex->width; @@ -343,38 +346,40 @@ xoverlay_draw_rect_textured(float x, float y, float w, float h, xoverlay_rgba_t float t0 = ty / tex->height; float t1 = (ty + th) / tex->height; - vertices[0].pos.x = x; - vertices[0].pos.y = y; - vertices[0].uv.x = s0; - vertices[0].uv.y = t1; + vertices[0].position.x = x; + vertices[0].position.y = y; + vertices[0].tex_coords.x = s0; + vertices[0].tex_coords.y = t1; vertices[0].color = *(vec4*)&color; + vertices[0].mode = DRAW_MODE_TEXTURED; - vertices[1].pos.x = x; - vertices[1].pos.y = y + h; - vertices[1].uv.x = s0; - vertices[1].uv.y = t0; + vertices[1].position.x = x; + vertices[1].position.y = y + h; + vertices[1].tex_coords.x = s0; + vertices[1].tex_coords.y = t0; vertices[1].color = *(vec4*)&color; + vertices[0].mode = DRAW_MODE_TEXTURED; - vertices[2].pos.x = x + w; - vertices[2].pos.y = y + h; - vertices[2].uv.x = s1; - vertices[2].uv.y = t0; + vertices[2].position.x = x + w; + vertices[2].position.y = y + h; + vertices[2].tex_coords.x = s1; + vertices[2].tex_coords.y = t0; vertices[2].color = *(vec4*)&color; + vertices[2].mode = DRAW_MODE_TEXTURED; - vertices[3].pos.x = x + w; - vertices[3].pos.y = y; - vertices[3].uv.x = s1; - vertices[3].uv.y = t1; + vertices[3].position.x = x + w; + vertices[3].position.y = y; + vertices[3].tex_coords.x = s1; + vertices[3].tex_coords.y = t1; vertices[3].color = *(vec4*)&color; + vertices[3].mode = DRAW_MODE_TEXTURED; - dis_push_vertices(4, sizeof(struct vertex_v2ft2fc4f), vertices); - dis_push_indices(6, indices); + vertex_buffer_push_back(program.buffer, vertices, 4, indices, 6); } void draw_string_internal(float x, float y, const char *string, texture_font_t *fnt, vec4 color, float *out_x, float *out_y) { - float pen_x = x; float pen_y = y; float size_y = 0; @@ -386,7 +391,9 @@ draw_string_internal(float x, float y, const char *string, texture_font_t *fnt, return; GLuint indices[6 * len]; - struct vertex_v2ft2fc4f vertices[4 * len]; + struct vertex_main vertices[4 * len]; + + GLuint idx = program_next_index(); for (size_t i = 0; i < len; ++i) { @@ -409,26 +416,25 @@ draw_string_internal(float x, float y, const char *string, texture_font_t *fnt, float s1 = glyph->s1; float t1 = glyph->t1; - GLuint idx = dstream.next_index + i * 4; indices[i * 6 + 0] = idx; indices[i * 6 + 1] = idx + 1; indices[i * 6 + 2] = idx + 2; indices[i * 6 + 3] = idx + 2; indices[i * 6 + 4] = idx + 3; indices[i * 6 + 5] = idx; + idx += 6; - vertices[i * 4 + 0] = (struct vertex_v2ft2fc4f){ (vec2){ x0, y0 }, (vec2){ s0, t0 }, color }; - vertices[i * 4 + 1] = (struct vertex_v2ft2fc4f){ (vec2){ x0, y1 }, (vec2){ s0, t1 }, color }; - vertices[i * 4 + 2] = (struct vertex_v2ft2fc4f){ (vec2){ x1, y1 }, (vec2){ s1, t1 }, color }; - vertices[i * 4 + 3] = (struct vertex_v2ft2fc4f){ (vec2){ x1, y0 }, (vec2){ s1, t0 }, color }; + vertices[i * 4 + 0] = (struct vertex_main){ (vec2){ x0, y0 }, (vec2){ s0, t0 }, color, DRAW_MODE_FREETYPE }; + vertices[i * 4 + 1] = (struct vertex_main){ (vec2){ x0, y1 }, (vec2){ s0, t1 }, color, DRAW_MODE_FREETYPE }; + vertices[i * 4 + 2] = (struct vertex_main){ (vec2){ x1, y1 }, (vec2){ s1, t1 }, color, DRAW_MODE_FREETYPE }; + vertices[i * 4 + 3] = (struct vertex_main){ (vec2){ x1, y0 }, (vec2){ s1, t0 }, color, DRAW_MODE_FREETYPE }; pen_x += glyph->advance_x; if (glyph->height > size_y) size_y = glyph->height; } - dis_push_indices(6 * len, indices); - dis_push_vertices(4 * len, sizeof(struct vertex_v2ft2fc4f), vertices); + vertex_buffer_push_back(program.buffer, vertices, len * 4, indices, len * 6); if (out_x) *out_x = pen_x - x; @@ -441,9 +447,6 @@ xoverlay_draw_string(float x, float y, const char *string, xoverlay_font_handle_ if (xoverlay_library.mapped == 0 || xoverlay_library.drawing == 0) return; - ds_prepare_program(PROGRAM_FREETYPE); - ds_prepare_font(font); - texture_font_t *fnt = fontapi_get(font); if (fnt == NULL) { @@ -451,6 +454,8 @@ xoverlay_draw_string(float x, float y, const char *string, xoverlay_font_handle_ return; } + ds_bind_texture(fnt->atlas->id); + fnt->rendermode = RENDER_NORMAL; fnt->outline_thickness = 0.0f; @@ -463,9 +468,6 @@ xoverlay_draw_string_with_outline(float x, float y, const char *string, xoverlay if (xoverlay_library.mapped == 0 || xoverlay_library.drawing == 0) return; - ds_prepare_program(PROGRAM_FREETYPE); - ds_prepare_font(font); - if (adjust_outline_alpha) outline_color.a = color.a; @@ -476,6 +478,8 @@ xoverlay_draw_string_with_outline(float x, float y, const char *string, xoverlay return; } + ds_bind_texture(fnt->atlas->id); + fnt->rendermode = RENDER_OUTLINE_POSITIVE; fnt->outline_thickness = outline_width; draw_string_internal(x, y, string, fnt, *(vec4*)&outline_color, NULL, NULL); diff --git a/src/drawglx_internal.c b/src/drawglx_internal.c index ff4b4d9..e904201 100644 --- a/src/drawglx_internal.c +++ b/src/drawglx_internal.c @@ -20,252 +20,10 @@ drawglx_internal_init() return 0; } -/* STACK SAFE */ -void -dis_init() -{ - dstream.capacity = 128; - dstream.memory = malloc(dstream.capacity); - dstream.read_ptr = 0; - dstream.write_ptr = 0; - dstream.next_index = 0; -} - -/* STACK SAFE */ -void -dis_destroy() -{ - free(dstream.memory); -} - -/* STACK SAFE */ -void -dis_reset() -{ - dstream.write_ptr = 0; - dstream.read_ptr = 0; - dstream.next_index = 0; -} - -/* STACK SAFE */ -void -dis_reserve(size_t bytes) -{ - while (dstream.write_ptr + bytes > dstream.capacity) - { - dstream.capacity *= 2; - dstream.capacity += 4; - dstream.memory = realloc(dstream.memory, dstream.capacity); - } -} - -/* STACK SAFE */ -struct draw_instruction_t* -dis_last_pushed_instruction() -{ - if (dstream.write_ptr == 0) - { - return NULL; - } - if (dstream.last_draw_instruction_offset + sizeof(struct draw_instruction_t) > dstream.capacity) - { - return NULL; - } - return (struct draw_instruction_t *)(dstream.memory + dstream.last_draw_instruction_offset); -} - -/* STACK SAFE */ -void -dis_push_data(size_t bytes, void *data) -{ - dis_reserve(bytes); - memcpy(dstream.memory + dstream.write_ptr, data, bytes); - dstream.write_ptr += bytes; -} - -/* STACK SAFE */ -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_read_data(size_t bytes) -{ - void *result = dstream.memory + dstream.read_ptr; - dstream.read_ptr += bytes; - return result; -} - -void -dis_switch_program(int program) -{ - struct draw_instruction_t *last = dis_last_pushed_instruction(); - - if (last && last->type == DI_SWITCH_PROGRAM) - { - if (last->program != program) - { - last->program = program; - dstream.next_index = 0; - } - return; - } - else - { - struct draw_instruction_t instr; - - instr.type = DI_SWITCH_PROGRAM; - instr.program = program; - dstream.next_index = 0; - dis_push_instruction(instr); - } -} - -void -dis_push_vertices(size_t count, size_t vertex_size, void *vertex_data) -{ - struct draw_instruction_t *last = dis_last_pushed_instruction(); - dstream.next_index += count; - - 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(xoverlay_font_handle_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; -} - -void -dis_textureapi_switch_texture(xoverlay_texture_handle_t texture) -{ - struct draw_instruction_t *last = dis_last_pushed_instruction(); - - if (last && last->type == DI_TEXTUREAPI_BIND_TEXTURE) - { - last->thandle = texture; - return; - } - else - { - struct draw_instruction_t instr; - - instr.type = DI_TEXTUREAPI_BIND_TEXTURE; - instr.thandle = texture; - dis_push_instruction(instr); - } -} - - void ds_init() { memset(&ds, 0, sizeof(struct draw_state)); - dis_init(); - ds.program = -1; ds.font = 0; mat4_set_identity(&ds.projection); mat4_set_identity(&ds.view); @@ -276,7 +34,6 @@ ds_init() void ds_destroy() { - dis_destroy(); } void @@ -288,9 +45,9 @@ ds_mark_dirty() void ds_render_if_needed() { - if (ds.dirty && ds.program >= 0) + if (ds.dirty) { - programs[ds.program].render(); + program_draw(); } ds.dirty = 0; } @@ -323,6 +80,9 @@ ds_pre_render() glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_INDEX_ARRAY); + + ds.texture = 0; + ds.font = 0; } void @@ -335,139 +95,13 @@ ds_post_render() glXMakeContextCurrent(xoverlay_library.display, None, None, None); } -void -ds_render_next_frame() -{ - ds_pre_render(); - dis_finish(); - ds.program = -1; - ds.thandle = 0; - ds.font = 0; - ds.texture = 0; - ds.shader = 0; - struct draw_instruction_t *instr; - - instr = dis_fetch_instruction(); - char valid = 1; - - while (valid && instr) - { - switch (instr->type) - { - case DI_SWITCH_PROGRAM: - if (ds.program != instr->program) - { - ds_render_if_needed(); - if (ds.program >= 0 && programs[ds.program].unload) - programs[ds.program].unload(); - ds.program = instr->program; - if (programs[ds.program].load) - programs[ds.program].load(); - } - break; - case DI_PUSH_VERTICES: - ds_mark_dirty(); - float *vert = dis_read_data(instr->count * programs[ds.program].vertex_size); - vertex_buffer_push_back_vertices(programs[ds.program].vertex, vert, instr->count); - break; - case DI_PUSH_INDICES: - ds_mark_dirty(); - GLuint *indices = dis_read_data(instr->count * sizeof(GLuint)); - vertex_buffer_push_back_indices(programs[ds.program].vertex, indices, instr->count); - break; - case DI_PROGRAM_SWITCH_TEXTURE: - ds_bind_texture(instr->texture); - break; - case DI_PROGRAM_SWITCH_FONT: - program_freetype_switch_font(instr->font); - break; - case DI_TEXTUREAPI_BIND_TEXTURE: - textureapi_bind(instr->thandle); - break; - case DI_INVALID_INSTRUCTION: - case DI_TERMINATE: - default: - valid = 0; - break; - - } - instr = dis_fetch_instruction(); - } - ds_render_if_needed(); - if (ds.program >= 0 && programs[ds.program].unload) - { - programs[ds.program].unload(); - ds.program = -1; - } - dis_reset(); - ds_post_render(); -} - void ds_bind_texture(GLuint texture) { if (ds.texture != texture) { + ds_render_if_needed(); ds.texture = texture; glBindTexture(GL_TEXTURE_2D, texture); } } - -void -ds_use_shader(GLuint shader) -{ - if (ds.shader != shader) - { - ds.shader = shader; - glUseProgram(shader); - } -} - -void -ds_use_font(xoverlay_font_handle_t font) -{ - if (ds.font != font) - { - ds.font = font; - } -} - -void -ds_prepare_texture_handle(xoverlay_texture_handle_t handle) -{ - if (handle != ds.thandle) - { - dis_textureapi_switch_texture(handle); - ds.thandle = handle; - } -} - -void -ds_prepare_program(int program) -{ - if (program != ds.program) - { - dis_switch_program(program); - ds.program = program; - } -} - -void -ds_prepare_texture(GLuint texture) -{ - if (texture != ds.texture) - { - dis_program_switch_texture(texture); - ds.texture = texture; - } -} - -void -ds_prepare_font(xoverlay_font_handle_t font) -{ - if (font != ds.font) - { - dis_program_switch_font(font); - ds.font = font; - } -} diff --git a/src/overlay.c b/src/overlay.c index 0ad8b29..aea7d97 100644 --- a/src/overlay.c +++ b/src/overlay.c @@ -287,13 +287,13 @@ void xoverlay_poll_events() void xoverlay_draw_begin() { if (!xoverlay_library.init) return; - + ds_pre_render(); xoverlay_library.drawing = 1; } void xoverlay_draw_end() { if (!xoverlay_library.init) return; - ds_render_next_frame(); + ds_post_render(); xoverlay_library.drawing = 0; } diff --git a/src/program.c b/src/program.c index 70697da..31a5376 100644 --- a/src/program.c +++ b/src/program.c @@ -1,3 +1,7 @@ +#include "program.h" +#include "log.h" +#include "drawglx_internal.h" + GLuint compile_shader(const char *source, GLenum type) { GLint status; @@ -27,6 +31,8 @@ setup_matrices(GLuint shader, int textures) } const char *shader_ultimate_vert = + "#version 150\n" + "\n" "uniform mat4 model;\n" "uniform mat4 view;\n" "uniform mat4 projection;\n" @@ -35,30 +41,37 @@ const char *shader_ultimate_vert = "attribute vec4 color;\n" "attribute uint draw_mode;\n" "flat out uint frag_DrawMode;\n" + "out vec4 frag_Color;\n" + "out vec2 frag_TexCoord;\n" "void main()\n" "{\n" - " gl_TexCoord[0].xy = tex_coord.xy;\n" - " gl_FrontColor = color;\n" - " gl_Position = projection*(view*(model*vec4(vertex,0.0,1.0)));\n" - " frag_DrawMode = draw_mode;\n" - "}"; + " frag_TexCoord = tex_coord;\n" + " frag_Color = color;\n" + " gl_Position = projection*(view*(model*vec4(vertex,0.0,1.0)));\n" + " frag_DrawMode = draw_mode;\n" + "}\n"; const char *shader_ultimate_frag = + "#version 150\n" + "\n" "uniform sampler2D texture;\n" - "flat in uint frag_DrawMode\n" + "out vec4 out_Color;\n" + "in vec4 frag_Color;\n" + "in vec2 frag_TexCoord;\n" + "flat in uint frag_DrawMode;\n" "void main()\n" "{\n" - " if (frag_DrawMode == 1)\n" - " gl_FragColor = gl_Color;\n" + " if (frag_DrawMode == 1u)\n" + " out_Color = frag_Color;\n" " else\n" " {\n" - " vec4 tex = texture2D(texture, gl_TexCoord[0].xy);\n" - " if (frag_DrawMode == 2)\n" - " gl_FragColor = gl_Color * tex\n" - " else if (frag_DrawMode == 3)\n" - " gl_FragColor = vec4(gl_Color.rgb, gl_Color.a * texture2D(texture, gl_TexCoord[0].xy).r);\n" + " vec4 tex = texture2D(texture, frag_TexCoord);\n" + " if (frag_DrawMode == 2u)\n" + " out_Color = frag_Color * tex;\n" + " else if (frag_DrawMode == 3u)\n" + " out_Color = vec4(in_Color.rgb, frag_Color.a * texture2D(texture, frag_TexCoord).r);\n" " else\n" - " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" - "}"; + " out_Color = vec4(1.0, 0.0, 0.0, 1.0);\n" + "}\n"; void program_init() @@ -67,20 +80,47 @@ program_init() program.shader = glCreateProgram(); GLint status; GLuint sh_frag = compile_shader(shader_ultimate_frag, GL_FRAGMENT_SHADER); - glAttachShader(program->shader, sh_frag); + glAttachShader(program.shader, sh_frag); glDeleteShader(sh_frag); GLuint sh_vert = compile_shader(shader_ultimate_vert, GL_VERTEX_SHADER); - glAttachShader(program->shader, sh_vert); + glAttachShader(program.shader, sh_vert); glDeleteShader(sh_vert); - glLinkProgram(program->shader); - glGetProgramiv(program->shader, GL_LINK_STATUS, &status); + glLinkProgram(program.shader); + glGetProgramiv(program.shader, GL_LINK_STATUS, &status); if (status == GL_FALSE) { - char error_log[256]; - glGetShaderInfoLog(program->shader, sizeof(error_log), NULL, error_log); + char error_log[512]; + glGetShaderInfoLog(program.shader, sizeof(error_log), NULL, error_log); log_write("GL Shader linking error:\n%s\n", error_log); exit(1); } -} \ No newline at end of file + glUseProgram(program.shader); + glUniformMatrix4fv(glGetUniformLocation(program.shader, "model"), 1, 0, ds.model.data); + glUniformMatrix4fv(glGetUniformLocation(program.shader, "view"), 1, 0, ds.view.data); + glUniformMatrix4fv(glGetUniformLocation(program.shader, "projection"), 1, 0, ds.projection.data); + glUniform1i(glGetUniformLocation(program.shader, "texture"), 0); + glUseProgram(0); + program.shader_active = 0; +} + +void +program_draw() +{ + glUseProgram(program.shader); + vertex_buffer_render(program.buffer, GL_TRIANGLES); + glUseProgram(0); +} + +void +program_reset() +{ + vertex_buffer_clear(program.buffer); +} + +unsigned +program_next_index() +{ + return program.buffer->vertices->size; +} diff --git a/src/program_freetype.c b/src/program_freetype.c deleted file mode 100644 index 7c0dbb2..0000000 --- a/src/program_freetype.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * program_freetype.c - * - * Created on: Nov 10, 2017 - * Author: nullifiedcat - */ - -#include - -#include "freetype-gl.h" -#include "programs.h" -#include "texture-atlas.h" -#include "drawglx_internal.h" -#include "log.h" - -DECL_PROGRAM_INIT(freetype) -{ -} - -DECL_PROGRAM_LOAD(freetype) -{ - vertex_buffer_clear(programs[PROGRAM_FREETYPE].vertex); - ds_use_shader(programs[PROGRAM_FREETYPE].shader); - texture_font_t *fnt = fontapi_get(ds.font); - if (fnt == NULL) - return; - ds_bind_texture(fnt->atlas->id); -} - -DECL_PROGRAM_RENDER(freetype) -{ - if (programs[PROGRAM_FREETYPE].vertex->indices->size == 0) - return; - vertex_buffer_render(programs[PROGRAM_FREETYPE].vertex, GL_TRIANGLES); -} - -DECL_PROGRAM_UNLOAD(freetype) -{ - -} - -DECL_PROGRAM_DESTROY(freetype) -{ -} - -void -program_freetype_switch_font(xoverlay_font_handle_t font) -{ - texture_font_t *fnt = fontapi_get(font); - if (fnt == NULL) - return; - if (fnt->atlas->id == 0) - { - glGenTextures(1, &fnt->atlas->id); - } - ds_bind_texture(fnt->atlas->id); - if (fnt->atlas->dirty) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, fnt->atlas->width, fnt->atlas->height, 0, GL_RED, GL_UNSIGNED_BYTE, fnt->atlas->data); - fnt->atlas->dirty = 0; - } -} - diff --git a/src/program_triangles_plain.c b/src/program_triangles_plain.c deleted file mode 100644 index 9a32bff..0000000 --- a/src/program_triangles_plain.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * program_triangles_plain.c - * - * Created on: Nov 10, 2017 - * Author: nullifiedcat - */ - -#include - -#include "programs.h" -#include "drawglx_internal.h" -#include "log.h" - -DECL_PROGRAM_INIT(triangles_plain) -{ - -} - -DECL_PROGRAM_LOAD(triangles_plain) -{ - ds_use_shader(programs[PROGRAM_TRIANGLES_PLAIN].shader); - vertex_buffer_clear(programs[PROGRAM_TRIANGLES_PLAIN].vertex); -} - -DECL_PROGRAM_RENDER(triangles_plain) -{ - if (programs[PROGRAM_TRIANGLES_PLAIN].vertex->indices->size == 0) - return; - vertex_buffer_render(programs[PROGRAM_TRIANGLES_PLAIN].vertex, GL_TRIANGLES); -} - -DECL_PROGRAM_UNLOAD(triangles_plain) -{ - -} - -DECL_PROGRAM_DESTROY(triangles_plain) -{ - -} diff --git a/src/program_triangles_textured.c b/src/program_triangles_textured.c deleted file mode 100644 index a2c74ed..0000000 --- a/src/program_triangles_textured.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * program_triangles_textured.c - * - * Created on: Nov 10, 2017 - * Author: nullifiedcat - */ - -#include - -#include "programs.h" -#include "drawglx_internal.h" -#include "log.h" - -DECL_PROGRAM_INIT(triangles_textured) -{ - -} - -DECL_PROGRAM_LOAD(triangles_textured) -{ - ds_use_shader(programs[PROGRAM_TRIANGLES_TEXTURED].shader); - vertex_buffer_clear(programs[PROGRAM_TRIANGLES_TEXTURED].vertex); -} - -DECL_PROGRAM_RENDER(triangles_textured) -{ - if (programs[PROGRAM_TRIANGLES_TEXTURED].vertex->indices->size == 0) - return; - vertex_buffer_render(programs[PROGRAM_TRIANGLES_TEXTURED].vertex, GL_TRIANGLES); -} - -DECL_PROGRAM_UNLOAD(triangles_textured) -{ - -} - -DECL_PROGRAM_DESTROY(triangles_textured) -{ - -} diff --git a/src/programs.c b/src/programs.c deleted file mode 100644 index ba0dfe0..0000000 --- a/src/programs.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * draw_commands.c - * - * Created on: Nov 10, 2017 - * Author: nullifiedcat - */ - -#include "drawglx_internal.h" -#include "log.h" - -#include - -GLuint compile_shader(const char *source, GLenum type) -{ - GLint status; - GLuint shader = glCreateShader(type); - glShaderSource(shader, 1, &source, 0); - glCompileShader(shader); - glGetShaderiv(shader, GL_COMPILE_STATUS, &status); - if (status == GL_FALSE) - { - char error_log[256]; - glGetShaderInfoLog(shader, sizeof(error_log), NULL, error_log); - log_write("GL Shader compilation error:\n%s\n", error_log); - exit(1); - } - return shader; -} - -void -setup_matrices(GLuint shader, int textures) -{ - glUseProgram(shader); - glUniformMatrix4fv(glGetUniformLocation(shader, "model"), 1, 0, ds.model.data); - glUniformMatrix4fv(glGetUniformLocation(shader, "view"), 1, 0, ds.view.data); - glUniformMatrix4fv(glGetUniformLocation(shader, "projection"), 1, 0, ds.projection.data); - if (textures) - glUniform1i(glGetUniformLocation(shader, "texture"), 0); - glUseProgram(0); -} - -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_empty_fn render, program_callback_empty_fn unload, program_callback_empty_fn destroy) -{ - program->init = init; - program->load = load; - program->render = render; - program->unload = unload; - program->destroy = destroy; - program->vertex = vertex_buffer_new(vertex_format); - - program->shader = glCreateProgram(); - GLint status; - - GLuint sh_frag = compile_shader(shader_frag, GL_FRAGMENT_SHADER); - glAttachShader(program->shader, sh_frag); - glDeleteShader(sh_frag); - - GLuint sh_vert = compile_shader(shader_vert, GL_VERTEX_SHADER); - glAttachShader(program->shader, sh_vert); - glDeleteShader(sh_vert); - - glLinkProgram(program->shader); - glGetProgramiv(program->shader, GL_LINK_STATUS, &status); - if (status == GL_FALSE) - { - char error_log[256]; - glGetShaderInfoLog(program->shader, sizeof(error_log), NULL, error_log); - log_write("GL Shader linking error:\n%s\n", error_log); - exit(1); - } - - program->vertex_size = program->vertex->vertices->item_size; -} - -#define PROGRAM_INIT_INPLACE(location, format, fragment, vertex, name) \ - program_init_inplace(location, format, fragment, vertex, PROGRAM_INIT(name), PROGRAM_LOAD(name), PROGRAM_RENDER(name), PROGRAM_UNLOAD(name), PROGRAM_DESTROY(name)) - -const char *shader_v2fc4f_vert = - "uniform mat4 model;\n" - "uniform mat4 view;\n" - "uniform mat4 projection;\n" - "attribute vec2 vertex;\n" - "attribute vec4 color;\n" - "void main()\n" - "{\n" - " gl_FrontColor = color;\n" - " gl_Position = projection*(view*(model*vec4(vertex,0.0,1.0)));\n" - "}"; -const char *shader_v2fc4f_frag = - "void main() {\n" - " gl_FragColor = gl_Color;\n" - "}"; -const char *shader_v2ft2fc4f_vert = - "uniform mat4 model;\n" - "uniform mat4 view;\n" - "uniform mat4 projection;\n" - - - - -void -program_init_everything() -{ - log_write("Initializing programs\n"); - PROGRAM_INIT_INPLACE(&programs[PROGRAM_TRIANGLES_PLAIN], "vertex:2f,color:4f", shader_v2fc4f_frag, shader_v2fc4f_vert, triangles_plain); - setup_matrices(programs[PROGRAM_TRIANGLES_PLAIN].shader, 0); - PROGRAM_INIT_INPLACE(&programs[PROGRAM_TRIANGLES_TEXTURED], "vertex:2f,tex_coord:2f,color:4f", shader_v2ft2fc4f_frag, shader_v2ft2fc4f_vert, triangles_textured); - setup_matrices(programs[PROGRAM_TRIANGLES_TEXTURED].shader, 1); - PROGRAM_INIT_INPLACE(&programs[PROGRAM_FREETYPE], "vertex:2f,tex_coord:2f,color:4f", shader_v2ft2fc4f_freetype_frag, shader_v2ft2fc4f_vert, freetype); - setup_matrices(programs[PROGRAM_FREETYPE].shader, 1); -}