gui cleanup
parent
071d73dbe2
commit
02ebdb77b2
21
bind/v4k.lua
21
bind/v4k.lua
|
@ -1519,7 +1519,7 @@ ffi.cdef([[
|
||||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:vec2 fire;
|
//lcpp INF [0000] vec2: macro name but used as C declaration in:vec2 fire;
|
||||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:vec4 pos;
|
//lcpp INF [0000] vec4: macro name but used as C declaration in:vec4 pos;
|
||||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:vec2 sca;
|
//lcpp INF [0000] vec2: macro name but used as C declaration in:vec2 sca;
|
||||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:void (*draw_rect_func)(void* userdata, gui_state_t state, const char *skin, vec4 rect);
|
//lcpp INF [0000] vec4: macro name but used as C declaration in:void (*draw_rect_func)(void* userdata, const char *skin, vec4 rect);
|
||||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:API void gui_panel(int id, vec4 rect, const char *skin);
|
//lcpp INF [0000] vec4: macro name but used as C declaration in:API void gui_panel(int id, vec4 rect, const char *skin);
|
||||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC void gui_panel(int id, vec4 rect, const char *skin);
|
//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC void gui_panel(int id, vec4 rect, const char *skin);
|
||||||
//lcpp INF [0000] vec4: macro name but used as C declaration in: void gui_panel(int id, vec4 rect, const char *skin);
|
//lcpp INF [0000] vec4: macro name but used as C declaration in: void gui_panel(int id, vec4 rect, const char *skin);
|
||||||
|
@ -3297,21 +3297,8 @@ enum { OBJTYPE_sprite_t = 10 }; typedef struct { unsigned static_assert_on
|
||||||
sprite_t*sprite_new(const char *ase, int bindings[6]);
|
sprite_t*sprite_new(const char *ase, int bindings[6]);
|
||||||
void sprite_del(sprite_t *s);
|
void sprite_del(sprite_t *s);
|
||||||
void sprite_setanim(sprite_t *s, unsigned name);
|
void sprite_setanim(sprite_t *s, unsigned name);
|
||||||
enum {
|
|
||||||
GUI_PANEL,
|
|
||||||
GUI_BUTTON,
|
|
||||||
};
|
|
||||||
typedef struct gui_state_t {
|
|
||||||
int kind;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
bool held;
|
|
||||||
bool hover;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
} gui_state_t;
|
|
||||||
typedef struct guiskin_t {
|
typedef struct guiskin_t {
|
||||||
void (*draw_rect_func)(void* userdata, gui_state_t state, const char *skin, vec4 rect);
|
void (*draw_rect_func)(void* userdata, const char *skin, vec4 rect);
|
||||||
void (*free)(void* userdata);
|
void (*free)(void* userdata);
|
||||||
void *userdata;
|
void *userdata;
|
||||||
} guiskin_t;
|
} guiskin_t;
|
||||||
|
@ -3320,13 +3307,11 @@ void *userdata;
|
||||||
void gui_panel(int id, vec4 rect, const char *skin);
|
void gui_panel(int id, vec4 rect, const char *skin);
|
||||||
bool gui_button(int id, vec4 rect, const char *skin);
|
bool gui_button(int id, vec4 rect, const char *skin);
|
||||||
void gui_popskin();
|
void gui_popskin();
|
||||||
guiskin_t gui_skinned(const char *inifile, float scale);
|
|
||||||
typedef struct skinned_t {
|
typedef struct skinned_t {
|
||||||
atlas_t atlas;
|
atlas_t atlas;
|
||||||
float scale;
|
float scale;
|
||||||
char *panel;
|
|
||||||
char *button;
|
|
||||||
} skinned_t;
|
} skinned_t;
|
||||||
|
guiskin_t gui_skinned(const char *inifile, float scale);
|
||||||
void* thread( int (*thread_func)(void* user_data), void* user_data );
|
void* thread( int (*thread_func)(void* user_data), void* user_data );
|
||||||
void thread_destroy( void *thd );
|
void thread_destroy( void *thd );
|
||||||
int argc();
|
int argc();
|
||||||
|
|
|
@ -18115,24 +18115,8 @@ API void sprite_setanim(sprite_t *s, unsigned name);
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// game ui
|
// game ui
|
||||||
|
|
||||||
enum {
|
|
||||||
GUI_PANEL,
|
|
||||||
GUI_BUTTON,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct gui_state_t {
|
|
||||||
int kind;
|
|
||||||
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
bool held;
|
|
||||||
bool hover;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
} gui_state_t;
|
|
||||||
|
|
||||||
typedef struct guiskin_t {
|
typedef struct guiskin_t {
|
||||||
void (*draw_rect_func)(void* userdata, gui_state_t state, const char *skin, vec4 rect);
|
void (*draw_rect_func)(void* userdata, const char *skin, vec4 rect);
|
||||||
void (*free)(void* userdata);
|
void (*free)(void* userdata);
|
||||||
void *userdata;
|
void *userdata;
|
||||||
} guiskin_t;
|
} guiskin_t;
|
||||||
|
@ -18148,19 +18132,15 @@ API void gui_popskin();
|
||||||
#define gui_panel(...) gui_panel(__LINE__, __VA_ARGS__)
|
#define gui_panel(...) gui_panel(__LINE__, __VA_ARGS__)
|
||||||
#define gui_button(...) gui_button(__LINE__, __VA_ARGS__)
|
#define gui_button(...) gui_button(__LINE__, __VA_ARGS__)
|
||||||
|
|
||||||
// default skins
|
// default renderers
|
||||||
API guiskin_t gui_skinned(const char *inifile, float scale);
|
|
||||||
|
|
||||||
|
/// skinned
|
||||||
typedef struct skinned_t {
|
typedef struct skinned_t {
|
||||||
atlas_t atlas;
|
atlas_t atlas;
|
||||||
float scale;
|
float scale;
|
||||||
// unsigned framenum;
|
|
||||||
|
|
||||||
//skins
|
|
||||||
char *panel;
|
|
||||||
char *button;
|
|
||||||
} skinned_t;
|
} skinned_t;
|
||||||
|
|
||||||
|
API guiskin_t gui_skinned(const char *inifile, float scale);
|
||||||
#line 0
|
#line 0
|
||||||
|
|
||||||
#line 1 "v4k_system.h"
|
#line 1 "v4k_system.h"
|
||||||
|
@ -358851,39 +358831,11 @@ vec2 font_rect(const char *str) {
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// game ui (utils)
|
// game ui (utils)
|
||||||
|
|
||||||
API vec2i draw_window_ui();
|
API void gui_drawrect( texture_t spritesheet, vec2 tex_start, vec2 tex_end, int rgba, vec2 start, vec2 end );
|
||||||
|
|
||||||
API void draw_rect(int rgba, vec2 start, vec2 end );
|
|
||||||
API void draw_rect_tex( texture_t texture, int rgba, vec2 start, vec2 end );
|
|
||||||
API void draw_rect_sheet( texture_t spritesheet, vec2 tex_start, vec2 tex_end, int rgba, vec2 start, vec2 end );
|
|
||||||
|
|
||||||
#define draw_rect_borders(color, x, y, w, h, borderWeight) do { \
|
|
||||||
int x1 = (x); \
|
|
||||||
int y1 = (y); \
|
|
||||||
int x2 = (x) + (w) - 1; \
|
|
||||||
int y2 = (y) + (h) - 1; \
|
|
||||||
draw_rect(color, vec2(x1, y1), vec2(x2, y1 + (borderWeight) - 1)); \
|
|
||||||
draw_rect(color, vec2(x1, y1), vec2(x1 + (borderWeight) - 1, y2)); \
|
|
||||||
draw_rect(color, vec2(x1, y2 - (borderWeight) + 1), vec2(x2, y2)); \
|
|
||||||
draw_rect(color, vec2(x2 - (borderWeight) + 1, y1), vec2(x2, y2)); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
// #define lay_draw_rect(rgba, rect) draw_rect(rgba, vec2(rect.e[0], rect.e[1]), vec2(rect.e[0]+rect.e[2], rect.e[1]+rect.e[3]))
|
|
||||||
// #define lay_draw_rect_borders(rgba, rect, borderWeight) draw_rect_borders(rgba, rect.e[0], rect.e[1], rect.e[2], rect.e[3], borderWeight)
|
|
||||||
// #define lay_draw_rect_tex(tex, rgba, rect) draw_rect_tex(tex, rgba, vec2(rect.e[0], rect.e[1]), vec2(rect.e[0]+rect.e[2], rect.e[1]+rect.e[3]))
|
|
||||||
// #define l2m(rect) (vec4(rect.e[0]+rect.e[2], rect.e[1]+rect.e[3]))
|
|
||||||
#define v42v2(rect) vec2(rect.x,rect.y), vec2(rect.z,rect.w)
|
#define v42v2(rect) vec2(rect.x,rect.y), vec2(rect.z,rect.w)
|
||||||
|
|
||||||
|
void gui_drawrect( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, vec2 start, vec2 end ) {
|
||||||
|
|
||||||
vec2i draw_window_ui() {
|
|
||||||
vec2 dpi = ifdef(osx, window_dpi(), vec2(1,1));
|
|
||||||
int w = window_width();
|
|
||||||
int h = window_height();
|
|
||||||
return vec2i(w/dpi.x, h/dpi.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_rect_sheet( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, vec2 start, vec2 end ) {
|
|
||||||
float gamma = 1;
|
float gamma = 1;
|
||||||
static int program = -1, vbo = -1, vao = -1, u_inv_gamma = -1, u_tint = -1, u_has_tex = -1, u_window_width = -1, u_window_height = -1;
|
static int program = -1, vbo = -1, vao = -1, u_inv_gamma = -1, u_tint = -1, u_has_tex = -1, u_window_width = -1, u_window_height = -1;
|
||||||
vec2 dpi = ifdef(osx, window_dpi(), vec2(1,1));
|
vec2 dpi = ifdef(osx, window_dpi(), vec2(1,1));
|
||||||
|
@ -358911,7 +358863,6 @@ void draw_rect_sheet( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba,
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
|
GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
|
||||||
// glEnable( GL_BLEND );
|
|
||||||
glUseProgram( program );
|
glUseProgram( program );
|
||||||
glUniform1f( u_inv_gamma, 1.0f / (gamma + !gamma) );
|
glUniform1f( u_inv_gamma, 1.0f / (gamma + !gamma) );
|
||||||
|
|
||||||
|
@ -358963,20 +358914,20 @@ void draw_rect_sheet( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba,
|
||||||
glBindVertexArray( 0 );
|
glBindVertexArray( 0 );
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glUseProgram( 0 );
|
glUseProgram( 0 );
|
||||||
// glDisable( GL_BLEND );
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_rect_tex( texture_t texture, int rgba, vec2 start, vec2 end ) {
|
|
||||||
draw_rect_sheet(texture, vec2(0, 0), vec2(texture.w, texture.h), rgba, start, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_rect(int rgba, vec2 start, vec2 end ) {
|
|
||||||
draw_rect_tex((texture_t){0}, rgba, start, end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// game ui
|
// game ui
|
||||||
|
|
||||||
|
typedef struct gui_state_t {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
bool held;
|
||||||
|
bool hover;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} gui_state_t;
|
||||||
|
|
||||||
static __thread array(guiskin_t) skins=0;
|
static __thread array(guiskin_t) skins=0;
|
||||||
static __thread guiskin_t *last_skin=0;
|
static __thread guiskin_t *last_skin=0;
|
||||||
static __thread map(int, gui_state_t) ctl_states=0; //@leak
|
static __thread map(int, gui_state_t) ctl_states=0; //@leak
|
||||||
|
@ -358998,15 +358949,13 @@ void *gui_userdata() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
gui_state_t *gui_getstate(int id, int kind) {
|
gui_state_t *gui_getstate(int id) {
|
||||||
if (!ctl_states) map_init(ctl_states, less_int, hash_int);
|
if (!ctl_states) map_init(ctl_states, less_int, hash_int);
|
||||||
static gui_state_t st={0};
|
return map_find_or_add(ctl_states, id, (gui_state_t){0});
|
||||||
st.kind=kind;
|
|
||||||
return map_find_or_add(ctl_states, id, st);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool (gui_button)(int id, vec4 r, const char *skin) {
|
bool (gui_button)(int id, vec4 r, const char *skin) {
|
||||||
gui_state_t *entry = gui_getstate(id, GUI_BUTTON);
|
gui_state_t *entry = gui_getstate(id);
|
||||||
bool was_clicked=0;
|
bool was_clicked=0;
|
||||||
entry->hover = false;
|
entry->hover = false;
|
||||||
|
|
||||||
|
@ -359022,20 +358971,14 @@ bool (gui_button)(int id, vec4 r, const char *skin) {
|
||||||
entry->held = false;
|
entry->held = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_skin->draw_rect_func) last_skin->draw_rect_func(last_skin->userdata, *entry, skin, r);
|
char *btn = va("%s%s", skin?skin:"button", entry->held?"_press":entry->hover?"_hover":"");
|
||||||
else {
|
if (last_skin->draw_rect_func) last_skin->draw_rect_func(last_skin->userdata, btn, r);
|
||||||
draw_rect(entry->held ? 0x111111FF : entry->hover ? 0xEEEEEEFF : 0xFFFFFFFF, v42v2(r));
|
|
||||||
}
|
|
||||||
|
|
||||||
return was_clicked;
|
return was_clicked;
|
||||||
}
|
}
|
||||||
|
|
||||||
void (gui_panel)(int id, vec4 r, const char *skin) {
|
void (gui_panel)(int id, vec4 r, const char *skin) {
|
||||||
gui_state_t *entry = gui_getstate(id, GUI_PANEL);
|
if (last_skin->draw_rect_func) last_skin->draw_rect_func(last_skin->userdata, skin?skin:"panel", r);
|
||||||
if (last_skin->draw_rect_func) last_skin->draw_rect_func(last_skin->userdata, *entry, skin?skin:"panel", r);
|
|
||||||
else {
|
|
||||||
draw_rect(0xFFFFFFFF, v42v2(r));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skinned */
|
/* skinned */
|
||||||
|
@ -359048,26 +358991,23 @@ void skinned_free(void* userdata) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
atlas_slice_frame_t *skinned_getsliceframe(atlas_t *a, const char *name, const char *fallback) {
|
atlas_slice_frame_t *skinned_getsliceframe(atlas_t *a, const char *name) {
|
||||||
#define atlas_loop(n)\
|
for (int i = 0; i < array_count(a->slices); i++)
|
||||||
for (int i = 0; i < array_count(a->slices); i++)\
|
if (!strcmp(quark_string(&a->db, a->slices[i].name), name))
|
||||||
if (!strcmp(quark_string(&a->db, a->slices[i].name), n))\
|
return &a->slice_frames[a->slices[i].frames[0]];
|
||||||
return &a->slice_frames[a->slices[i].frames[0]];
|
|
||||||
atlas_loop(name);
|
|
||||||
atlas_loop(fallback);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
#undef atlas_loop
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void skinned_draw_missing_rect(vec4 r) {
|
void skinned_draw_missing_rect(vec4 r) {
|
||||||
draw_rect_tex(texture_checker(), 0xFFFFFFFF, v42v2(r));
|
vec4 size = vec4(0, 0, texture_checker().w, texture_checker().h);
|
||||||
|
gui_drawrect(texture_checker(), v42v2(size), 0x800080FF, v42v2(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r) {
|
void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r) {
|
||||||
if (!f->has_9slice) {
|
if (!f->has_9slice) {
|
||||||
draw_rect_sheet(a->tex, v42v2(f->bounds), 0xFFFFFFFF, v42v2(r));
|
gui_drawrect(a->tex, v42v2(f->bounds), 0xFFFFFFFF, v42v2(r));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359091,6 +359031,14 @@ void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r
|
||||||
vec4 bottom_middle_slice = {core.x, core.w, core.z, outer.w};
|
vec4 bottom_middle_slice = {core.x, core.w, core.z, outer.w};
|
||||||
vec4 bottom_right_slice = {core.z, core.w, outer.z, outer.w};
|
vec4 bottom_right_slice = {core.z, core.w, outer.z, outer.w};
|
||||||
|
|
||||||
|
// Ensure dest rectangle is large enough to render the whole element
|
||||||
|
if ((r.z-r.x) < (outer.z-outer.x) * scale) {
|
||||||
|
r.z = r.x + (outer.z-outer.x) * scale;
|
||||||
|
}
|
||||||
|
if ((r.w-r.y) < (outer.w-outer.y) * scale) {
|
||||||
|
r.w = r.y + (outer.w-outer.y) * scale;
|
||||||
|
}
|
||||||
|
|
||||||
vec4 top_left = {r.x, r.y, r.x + (core.x - outer.x) * scale, r.y + (core.y - outer.y) * scale};
|
vec4 top_left = {r.x, r.y, r.x + (core.x - outer.x) * scale, r.y + (core.y - outer.y) * scale};
|
||||||
vec4 top_right = {r.z - (outer.z - core.z) * scale, r.y, r.z, r.y + (core.y - outer.y) * scale};
|
vec4 top_right = {r.z - (outer.z - core.z) * scale, r.y, r.z, r.y + (core.y - outer.y) * scale};
|
||||||
vec4 bottom_left = {r.x, r.w - (outer.w - core.w) * scale, r.x + (core.x - outer.x) * scale, r.w};
|
vec4 bottom_left = {r.x, r.w - (outer.w - core.w) * scale, r.x + (core.x - outer.x) * scale, r.w};
|
||||||
|
@ -359103,41 +359051,24 @@ void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r
|
||||||
|
|
||||||
vec4 center = {top_left.z, top_left.w, top_right.x, bottom_right.y};
|
vec4 center = {top_left.z, top_left.w, top_right.x, bottom_right.y};
|
||||||
|
|
||||||
draw_rect_sheet(a->tex, v42v2(center_slice), 0xFFFFFFFF, v42v2(center));
|
gui_drawrect(a->tex, v42v2(center_slice), 0xFFFFFFFF, v42v2(center));
|
||||||
draw_rect_sheet(a->tex, v42v2(top_left_slice), 0xFFFFFFFF, v42v2(top_left));
|
gui_drawrect(a->tex, v42v2(top_left_slice), 0xFFFFFFFF, v42v2(top_left));
|
||||||
draw_rect_sheet(a->tex, v42v2(top_right_slice), 0xFFFFFFFF, v42v2(top_right));
|
gui_drawrect(a->tex, v42v2(top_right_slice), 0xFFFFFFFF, v42v2(top_right));
|
||||||
draw_rect_sheet(a->tex, v42v2(bottom_left_slice), 0xFFFFFFFF, v42v2(bottom_left));
|
gui_drawrect(a->tex, v42v2(bottom_left_slice), 0xFFFFFFFF, v42v2(bottom_left));
|
||||||
draw_rect_sheet(a->tex, v42v2(bottom_right_slice), 0xFFFFFFFF, v42v2(bottom_right));
|
gui_drawrect(a->tex, v42v2(bottom_right_slice), 0xFFFFFFFF, v42v2(bottom_right));
|
||||||
draw_rect_sheet(a->tex, v42v2(top_middle_slice), 0xFFFFFFFF, v42v2(top));
|
gui_drawrect(a->tex, v42v2(top_middle_slice), 0xFFFFFFFF, v42v2(top));
|
||||||
draw_rect_sheet(a->tex, v42v2(bottom_middle_slice), 0xFFFFFFFF, v42v2(bottom));
|
gui_drawrect(a->tex, v42v2(bottom_middle_slice), 0xFFFFFFFF, v42v2(bottom));
|
||||||
draw_rect_sheet(a->tex, v42v2(middle_left_slice), 0xFFFFFFFF, v42v2(left));
|
gui_drawrect(a->tex, v42v2(middle_left_slice), 0xFFFFFFFF, v42v2(left));
|
||||||
draw_rect_sheet(a->tex, v42v2(middle_right_slice), 0xFFFFFFFF, v42v2(right));
|
gui_drawrect(a->tex, v42v2(middle_right_slice), 0xFFFFFFFF, v42v2(right));
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void skinned_draw_rect(void* userdata, gui_state_t state, const char *skin, vec4 r) {
|
void skinned_draw_rect(void* userdata, const char *skin, vec4 r) {
|
||||||
skinned_t *a = C_CAST(skinned_t*, userdata);
|
skinned_t *a = C_CAST(skinned_t*, userdata);
|
||||||
|
|
||||||
switch (state.kind) {
|
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
||||||
case GUI_BUTTON: {
|
if (!f) skinned_draw_missing_rect(r);
|
||||||
char *btn = va("%s%s", skin?skin:a->button, state.held?"_press":state.hover?"_hover":"");
|
else skinned_draw_sprite(a->scale, &a->atlas, f, r);
|
||||||
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, btn, skin?skin:a->button);
|
|
||||||
if (!f) skinned_draw_missing_rect(r);
|
|
||||||
else skinned_draw_sprite(a->scale, &a->atlas, f, r);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case GUI_PANEL: {
|
|
||||||
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin?skin:a->panel, "");
|
|
||||||
if (!f) skinned_draw_missing_rect(r);
|
|
||||||
else skinned_draw_sprite(a->scale, &a->atlas, f, r);
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
void skinned_preset_skins(skinned_t *s) {
|
|
||||||
s->panel = "panel";
|
|
||||||
s->button = "button";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
guiskin_t gui_skinned(const char *inifile, float scale) {
|
guiskin_t gui_skinned(const char *inifile, float scale) {
|
||||||
|
@ -359148,7 +359079,6 @@ guiskin_t gui_skinned(const char *inifile, float scale) {
|
||||||
skin.userdata = a;
|
skin.userdata = a;
|
||||||
skin.draw_rect_func = skinned_draw_rect;
|
skin.draw_rect_func = skinned_draw_rect;
|
||||||
skin.free = skinned_free;
|
skin.free = skinned_free;
|
||||||
skinned_preset_skins(a);
|
|
||||||
return skin;
|
return skin;
|
||||||
}
|
}
|
||||||
#line 0
|
#line 0
|
||||||
|
|
|
@ -1,39 +1,11 @@
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// game ui (utils)
|
// game ui (utils)
|
||||||
|
|
||||||
API vec2i draw_window_ui();
|
API void gui_drawrect( texture_t spritesheet, vec2 tex_start, vec2 tex_end, int rgba, vec2 start, vec2 end );
|
||||||
|
|
||||||
API void draw_rect(int rgba, vec2 start, vec2 end );
|
|
||||||
API void draw_rect_tex( texture_t texture, int rgba, vec2 start, vec2 end );
|
|
||||||
API void draw_rect_sheet( texture_t spritesheet, vec2 tex_start, vec2 tex_end, int rgba, vec2 start, vec2 end );
|
|
||||||
|
|
||||||
#define draw_rect_borders(color, x, y, w, h, borderWeight) do { \
|
|
||||||
int x1 = (x); \
|
|
||||||
int y1 = (y); \
|
|
||||||
int x2 = (x) + (w) - 1; \
|
|
||||||
int y2 = (y) + (h) - 1; \
|
|
||||||
draw_rect(color, vec2(x1, y1), vec2(x2, y1 + (borderWeight) - 1)); \
|
|
||||||
draw_rect(color, vec2(x1, y1), vec2(x1 + (borderWeight) - 1, y2)); \
|
|
||||||
draw_rect(color, vec2(x1, y2 - (borderWeight) + 1), vec2(x2, y2)); \
|
|
||||||
draw_rect(color, vec2(x2 - (borderWeight) + 1, y1), vec2(x2, y2)); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
// #define lay_draw_rect(rgba, rect) draw_rect(rgba, vec2(rect.e[0], rect.e[1]), vec2(rect.e[0]+rect.e[2], rect.e[1]+rect.e[3]))
|
|
||||||
// #define lay_draw_rect_borders(rgba, rect, borderWeight) draw_rect_borders(rgba, rect.e[0], rect.e[1], rect.e[2], rect.e[3], borderWeight)
|
|
||||||
// #define lay_draw_rect_tex(tex, rgba, rect) draw_rect_tex(tex, rgba, vec2(rect.e[0], rect.e[1]), vec2(rect.e[0]+rect.e[2], rect.e[1]+rect.e[3]))
|
|
||||||
// #define l2m(rect) (vec4(rect.e[0]+rect.e[2], rect.e[1]+rect.e[3]))
|
|
||||||
#define v42v2(rect) vec2(rect.x,rect.y), vec2(rect.z,rect.w)
|
#define v42v2(rect) vec2(rect.x,rect.y), vec2(rect.z,rect.w)
|
||||||
|
|
||||||
|
void gui_drawrect( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, vec2 start, vec2 end ) {
|
||||||
|
|
||||||
vec2i draw_window_ui() {
|
|
||||||
vec2 dpi = ifdef(osx, window_dpi(), vec2(1,1));
|
|
||||||
int w = window_width();
|
|
||||||
int h = window_height();
|
|
||||||
return vec2i(w/dpi.x, h/dpi.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_rect_sheet( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, vec2 start, vec2 end ) {
|
|
||||||
float gamma = 1;
|
float gamma = 1;
|
||||||
static int program = -1, vbo = -1, vao = -1, u_inv_gamma = -1, u_tint = -1, u_has_tex = -1, u_window_width = -1, u_window_height = -1;
|
static int program = -1, vbo = -1, vao = -1, u_inv_gamma = -1, u_tint = -1, u_has_tex = -1, u_window_width = -1, u_window_height = -1;
|
||||||
vec2 dpi = ifdef(osx, window_dpi(), vec2(1,1));
|
vec2 dpi = ifdef(osx, window_dpi(), vec2(1,1));
|
||||||
|
@ -61,7 +33,6 @@ void draw_rect_sheet( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba,
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
|
GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
|
||||||
// glEnable( GL_BLEND );
|
|
||||||
glUseProgram( program );
|
glUseProgram( program );
|
||||||
glUniform1f( u_inv_gamma, 1.0f / (gamma + !gamma) );
|
glUniform1f( u_inv_gamma, 1.0f / (gamma + !gamma) );
|
||||||
|
|
||||||
|
@ -113,20 +84,20 @@ void draw_rect_sheet( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba,
|
||||||
glBindVertexArray( 0 );
|
glBindVertexArray( 0 );
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glUseProgram( 0 );
|
glUseProgram( 0 );
|
||||||
// glDisable( GL_BLEND );
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_rect_tex( texture_t texture, int rgba, vec2 start, vec2 end ) {
|
|
||||||
draw_rect_sheet(texture, vec2(0, 0), vec2(texture.w, texture.h), rgba, start, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_rect(int rgba, vec2 start, vec2 end ) {
|
|
||||||
draw_rect_tex((texture_t){0}, rgba, start, end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// game ui
|
// game ui
|
||||||
|
|
||||||
|
typedef struct gui_state_t {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
bool held;
|
||||||
|
bool hover;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} gui_state_t;
|
||||||
|
|
||||||
static __thread array(guiskin_t) skins=0;
|
static __thread array(guiskin_t) skins=0;
|
||||||
static __thread guiskin_t *last_skin=0;
|
static __thread guiskin_t *last_skin=0;
|
||||||
static __thread map(int, gui_state_t) ctl_states=0; //@leak
|
static __thread map(int, gui_state_t) ctl_states=0; //@leak
|
||||||
|
@ -148,15 +119,13 @@ void *gui_userdata() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
gui_state_t *gui_getstate(int id, int kind) {
|
gui_state_t *gui_getstate(int id) {
|
||||||
if (!ctl_states) map_init(ctl_states, less_int, hash_int);
|
if (!ctl_states) map_init(ctl_states, less_int, hash_int);
|
||||||
static gui_state_t st={0};
|
return map_find_or_add(ctl_states, id, (gui_state_t){0});
|
||||||
st.kind=kind;
|
|
||||||
return map_find_or_add(ctl_states, id, st);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool (gui_button)(int id, vec4 r, const char *skin) {
|
bool (gui_button)(int id, vec4 r, const char *skin) {
|
||||||
gui_state_t *entry = gui_getstate(id, GUI_BUTTON);
|
gui_state_t *entry = gui_getstate(id);
|
||||||
bool was_clicked=0;
|
bool was_clicked=0;
|
||||||
entry->hover = false;
|
entry->hover = false;
|
||||||
|
|
||||||
|
@ -172,20 +141,14 @@ bool (gui_button)(int id, vec4 r, const char *skin) {
|
||||||
entry->held = false;
|
entry->held = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_skin->draw_rect_func) last_skin->draw_rect_func(last_skin->userdata, *entry, skin, r);
|
char *btn = va("%s%s", skin?skin:"button", entry->held?"_press":entry->hover?"_hover":"");
|
||||||
else {
|
if (last_skin->draw_rect_func) last_skin->draw_rect_func(last_skin->userdata, btn, r);
|
||||||
draw_rect(entry->held ? 0x111111FF : entry->hover ? 0xEEEEEEFF : 0xFFFFFFFF, v42v2(r));
|
|
||||||
}
|
|
||||||
|
|
||||||
return was_clicked;
|
return was_clicked;
|
||||||
}
|
}
|
||||||
|
|
||||||
void (gui_panel)(int id, vec4 r, const char *skin) {
|
void (gui_panel)(int id, vec4 r, const char *skin) {
|
||||||
gui_state_t *entry = gui_getstate(id, GUI_PANEL);
|
if (last_skin->draw_rect_func) last_skin->draw_rect_func(last_skin->userdata, skin?skin:"panel", r);
|
||||||
if (last_skin->draw_rect_func) last_skin->draw_rect_func(last_skin->userdata, *entry, skin?skin:"panel", r);
|
|
||||||
else {
|
|
||||||
draw_rect(0xFFFFFFFF, v42v2(r));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skinned */
|
/* skinned */
|
||||||
|
@ -198,26 +161,23 @@ void skinned_free(void* userdata) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
atlas_slice_frame_t *skinned_getsliceframe(atlas_t *a, const char *name, const char *fallback) {
|
atlas_slice_frame_t *skinned_getsliceframe(atlas_t *a, const char *name) {
|
||||||
#define atlas_loop(n)\
|
for (int i = 0; i < array_count(a->slices); i++)
|
||||||
for (int i = 0; i < array_count(a->slices); i++)\
|
if (!strcmp(quark_string(&a->db, a->slices[i].name), name))
|
||||||
if (!strcmp(quark_string(&a->db, a->slices[i].name), n))\
|
return &a->slice_frames[a->slices[i].frames[0]];
|
||||||
return &a->slice_frames[a->slices[i].frames[0]];
|
|
||||||
atlas_loop(name);
|
|
||||||
atlas_loop(fallback);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
#undef atlas_loop
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void skinned_draw_missing_rect(vec4 r) {
|
void skinned_draw_missing_rect(vec4 r) {
|
||||||
draw_rect_tex(texture_checker(), 0xFFFFFFFF, v42v2(r));
|
vec4 size = vec4(0, 0, texture_checker().w, texture_checker().h);
|
||||||
|
gui_drawrect(texture_checker(), v42v2(size), 0x800080FF, v42v2(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r) {
|
void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r) {
|
||||||
if (!f->has_9slice) {
|
if (!f->has_9slice) {
|
||||||
draw_rect_sheet(a->tex, v42v2(f->bounds), 0xFFFFFFFF, v42v2(r));
|
gui_drawrect(a->tex, v42v2(f->bounds), 0xFFFFFFFF, v42v2(r));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,6 +201,14 @@ void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r
|
||||||
vec4 bottom_middle_slice = {core.x, core.w, core.z, outer.w};
|
vec4 bottom_middle_slice = {core.x, core.w, core.z, outer.w};
|
||||||
vec4 bottom_right_slice = {core.z, core.w, outer.z, outer.w};
|
vec4 bottom_right_slice = {core.z, core.w, outer.z, outer.w};
|
||||||
|
|
||||||
|
// Ensure dest rectangle is large enough to render the whole element
|
||||||
|
if ((r.z-r.x) < (outer.z-outer.x) * scale) {
|
||||||
|
r.z = r.x + (outer.z-outer.x) * scale;
|
||||||
|
}
|
||||||
|
if ((r.w-r.y) < (outer.w-outer.y) * scale) {
|
||||||
|
r.w = r.y + (outer.w-outer.y) * scale;
|
||||||
|
}
|
||||||
|
|
||||||
vec4 top_left = {r.x, r.y, r.x + (core.x - outer.x) * scale, r.y + (core.y - outer.y) * scale};
|
vec4 top_left = {r.x, r.y, r.x + (core.x - outer.x) * scale, r.y + (core.y - outer.y) * scale};
|
||||||
vec4 top_right = {r.z - (outer.z - core.z) * scale, r.y, r.z, r.y + (core.y - outer.y) * scale};
|
vec4 top_right = {r.z - (outer.z - core.z) * scale, r.y, r.z, r.y + (core.y - outer.y) * scale};
|
||||||
vec4 bottom_left = {r.x, r.w - (outer.w - core.w) * scale, r.x + (core.x - outer.x) * scale, r.w};
|
vec4 bottom_left = {r.x, r.w - (outer.w - core.w) * scale, r.x + (core.x - outer.x) * scale, r.w};
|
||||||
|
@ -253,41 +221,24 @@ void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r
|
||||||
|
|
||||||
vec4 center = {top_left.z, top_left.w, top_right.x, bottom_right.y};
|
vec4 center = {top_left.z, top_left.w, top_right.x, bottom_right.y};
|
||||||
|
|
||||||
draw_rect_sheet(a->tex, v42v2(center_slice), 0xFFFFFFFF, v42v2(center));
|
gui_drawrect(a->tex, v42v2(center_slice), 0xFFFFFFFF, v42v2(center));
|
||||||
draw_rect_sheet(a->tex, v42v2(top_left_slice), 0xFFFFFFFF, v42v2(top_left));
|
gui_drawrect(a->tex, v42v2(top_left_slice), 0xFFFFFFFF, v42v2(top_left));
|
||||||
draw_rect_sheet(a->tex, v42v2(top_right_slice), 0xFFFFFFFF, v42v2(top_right));
|
gui_drawrect(a->tex, v42v2(top_right_slice), 0xFFFFFFFF, v42v2(top_right));
|
||||||
draw_rect_sheet(a->tex, v42v2(bottom_left_slice), 0xFFFFFFFF, v42v2(bottom_left));
|
gui_drawrect(a->tex, v42v2(bottom_left_slice), 0xFFFFFFFF, v42v2(bottom_left));
|
||||||
draw_rect_sheet(a->tex, v42v2(bottom_right_slice), 0xFFFFFFFF, v42v2(bottom_right));
|
gui_drawrect(a->tex, v42v2(bottom_right_slice), 0xFFFFFFFF, v42v2(bottom_right));
|
||||||
draw_rect_sheet(a->tex, v42v2(top_middle_slice), 0xFFFFFFFF, v42v2(top));
|
gui_drawrect(a->tex, v42v2(top_middle_slice), 0xFFFFFFFF, v42v2(top));
|
||||||
draw_rect_sheet(a->tex, v42v2(bottom_middle_slice), 0xFFFFFFFF, v42v2(bottom));
|
gui_drawrect(a->tex, v42v2(bottom_middle_slice), 0xFFFFFFFF, v42v2(bottom));
|
||||||
draw_rect_sheet(a->tex, v42v2(middle_left_slice), 0xFFFFFFFF, v42v2(left));
|
gui_drawrect(a->tex, v42v2(middle_left_slice), 0xFFFFFFFF, v42v2(left));
|
||||||
draw_rect_sheet(a->tex, v42v2(middle_right_slice), 0xFFFFFFFF, v42v2(right));
|
gui_drawrect(a->tex, v42v2(middle_right_slice), 0xFFFFFFFF, v42v2(right));
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void skinned_draw_rect(void* userdata, gui_state_t state, const char *skin, vec4 r) {
|
void skinned_draw_rect(void* userdata, const char *skin, vec4 r) {
|
||||||
skinned_t *a = C_CAST(skinned_t*, userdata);
|
skinned_t *a = C_CAST(skinned_t*, userdata);
|
||||||
|
|
||||||
switch (state.kind) {
|
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
||||||
case GUI_BUTTON: {
|
if (!f) skinned_draw_missing_rect(r);
|
||||||
char *btn = va("%s%s", skin?skin:a->button, state.held?"_press":state.hover?"_hover":"");
|
else skinned_draw_sprite(a->scale, &a->atlas, f, r);
|
||||||
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, btn, skin?skin:a->button);
|
|
||||||
if (!f) skinned_draw_missing_rect(r);
|
|
||||||
else skinned_draw_sprite(a->scale, &a->atlas, f, r);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case GUI_PANEL: {
|
|
||||||
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin?skin:a->panel, "");
|
|
||||||
if (!f) skinned_draw_missing_rect(r);
|
|
||||||
else skinned_draw_sprite(a->scale, &a->atlas, f, r);
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
void skinned_preset_skins(skinned_t *s) {
|
|
||||||
s->panel = "panel";
|
|
||||||
s->button = "button";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
guiskin_t gui_skinned(const char *inifile, float scale) {
|
guiskin_t gui_skinned(const char *inifile, float scale) {
|
||||||
|
@ -298,6 +249,5 @@ guiskin_t gui_skinned(const char *inifile, float scale) {
|
||||||
skin.userdata = a;
|
skin.userdata = a;
|
||||||
skin.draw_rect_func = skinned_draw_rect;
|
skin.draw_rect_func = skinned_draw_rect;
|
||||||
skin.free = skinned_free;
|
skin.free = skinned_free;
|
||||||
skinned_preset_skins(a);
|
|
||||||
return skin;
|
return skin;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,8 @@
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// game ui
|
// game ui
|
||||||
|
|
||||||
enum {
|
|
||||||
GUI_PANEL,
|
|
||||||
GUI_BUTTON,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct gui_state_t {
|
|
||||||
int kind;
|
|
||||||
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
bool held;
|
|
||||||
bool hover;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
} gui_state_t;
|
|
||||||
|
|
||||||
typedef struct guiskin_t {
|
typedef struct guiskin_t {
|
||||||
void (*draw_rect_func)(void* userdata, gui_state_t state, const char *skin, vec4 rect);
|
void (*draw_rect_func)(void* userdata, const char *skin, vec4 rect);
|
||||||
void (*free)(void* userdata);
|
void (*free)(void* userdata);
|
||||||
void *userdata;
|
void *userdata;
|
||||||
} guiskin_t;
|
} guiskin_t;
|
||||||
|
@ -34,16 +18,12 @@ API void gui_popskin();
|
||||||
#define gui_panel(...) gui_panel(__LINE__, __VA_ARGS__)
|
#define gui_panel(...) gui_panel(__LINE__, __VA_ARGS__)
|
||||||
#define gui_button(...) gui_button(__LINE__, __VA_ARGS__)
|
#define gui_button(...) gui_button(__LINE__, __VA_ARGS__)
|
||||||
|
|
||||||
// default skins
|
// default renderers
|
||||||
API guiskin_t gui_skinned(const char *inifile, float scale);
|
|
||||||
|
|
||||||
|
/// skinned
|
||||||
typedef struct skinned_t {
|
typedef struct skinned_t {
|
||||||
atlas_t atlas;
|
atlas_t atlas;
|
||||||
float scale;
|
float scale;
|
||||||
// unsigned framenum;
|
|
||||||
|
|
||||||
//skins
|
|
||||||
char *panel;
|
|
||||||
char *button;
|
|
||||||
} skinned_t;
|
} skinned_t;
|
||||||
|
|
||||||
|
API guiskin_t gui_skinned(const char *inifile, float scale);
|
||||||
|
|
140
engine/v4k.c
140
engine/v4k.c
|
@ -11007,39 +11007,11 @@ vec2 font_rect(const char *str) {
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// game ui (utils)
|
// game ui (utils)
|
||||||
|
|
||||||
API vec2i draw_window_ui();
|
API void gui_drawrect( texture_t spritesheet, vec2 tex_start, vec2 tex_end, int rgba, vec2 start, vec2 end );
|
||||||
|
|
||||||
API void draw_rect(int rgba, vec2 start, vec2 end );
|
|
||||||
API void draw_rect_tex( texture_t texture, int rgba, vec2 start, vec2 end );
|
|
||||||
API void draw_rect_sheet( texture_t spritesheet, vec2 tex_start, vec2 tex_end, int rgba, vec2 start, vec2 end );
|
|
||||||
|
|
||||||
#define draw_rect_borders(color, x, y, w, h, borderWeight) do { \
|
|
||||||
int x1 = (x); \
|
|
||||||
int y1 = (y); \
|
|
||||||
int x2 = (x) + (w) - 1; \
|
|
||||||
int y2 = (y) + (h) - 1; \
|
|
||||||
draw_rect(color, vec2(x1, y1), vec2(x2, y1 + (borderWeight) - 1)); \
|
|
||||||
draw_rect(color, vec2(x1, y1), vec2(x1 + (borderWeight) - 1, y2)); \
|
|
||||||
draw_rect(color, vec2(x1, y2 - (borderWeight) + 1), vec2(x2, y2)); \
|
|
||||||
draw_rect(color, vec2(x2 - (borderWeight) + 1, y1), vec2(x2, y2)); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
// #define lay_draw_rect(rgba, rect) draw_rect(rgba, vec2(rect.e[0], rect.e[1]), vec2(rect.e[0]+rect.e[2], rect.e[1]+rect.e[3]))
|
|
||||||
// #define lay_draw_rect_borders(rgba, rect, borderWeight) draw_rect_borders(rgba, rect.e[0], rect.e[1], rect.e[2], rect.e[3], borderWeight)
|
|
||||||
// #define lay_draw_rect_tex(tex, rgba, rect) draw_rect_tex(tex, rgba, vec2(rect.e[0], rect.e[1]), vec2(rect.e[0]+rect.e[2], rect.e[1]+rect.e[3]))
|
|
||||||
// #define l2m(rect) (vec4(rect.e[0]+rect.e[2], rect.e[1]+rect.e[3]))
|
|
||||||
#define v42v2(rect) vec2(rect.x,rect.y), vec2(rect.z,rect.w)
|
#define v42v2(rect) vec2(rect.x,rect.y), vec2(rect.z,rect.w)
|
||||||
|
|
||||||
|
void gui_drawrect( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, vec2 start, vec2 end ) {
|
||||||
|
|
||||||
vec2i draw_window_ui() {
|
|
||||||
vec2 dpi = ifdef(osx, window_dpi(), vec2(1,1));
|
|
||||||
int w = window_width();
|
|
||||||
int h = window_height();
|
|
||||||
return vec2i(w/dpi.x, h/dpi.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_rect_sheet( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, vec2 start, vec2 end ) {
|
|
||||||
float gamma = 1;
|
float gamma = 1;
|
||||||
static int program = -1, vbo = -1, vao = -1, u_inv_gamma = -1, u_tint = -1, u_has_tex = -1, u_window_width = -1, u_window_height = -1;
|
static int program = -1, vbo = -1, vao = -1, u_inv_gamma = -1, u_tint = -1, u_has_tex = -1, u_window_width = -1, u_window_height = -1;
|
||||||
vec2 dpi = ifdef(osx, window_dpi(), vec2(1,1));
|
vec2 dpi = ifdef(osx, window_dpi(), vec2(1,1));
|
||||||
|
@ -11067,7 +11039,6 @@ void draw_rect_sheet( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba,
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
|
GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
|
||||||
// glEnable( GL_BLEND );
|
|
||||||
glUseProgram( program );
|
glUseProgram( program );
|
||||||
glUniform1f( u_inv_gamma, 1.0f / (gamma + !gamma) );
|
glUniform1f( u_inv_gamma, 1.0f / (gamma + !gamma) );
|
||||||
|
|
||||||
|
@ -11119,20 +11090,20 @@ void draw_rect_sheet( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba,
|
||||||
glBindVertexArray( 0 );
|
glBindVertexArray( 0 );
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glUseProgram( 0 );
|
glUseProgram( 0 );
|
||||||
// glDisable( GL_BLEND );
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_rect_tex( texture_t texture, int rgba, vec2 start, vec2 end ) {
|
|
||||||
draw_rect_sheet(texture, vec2(0, 0), vec2(texture.w, texture.h), rgba, start, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_rect(int rgba, vec2 start, vec2 end ) {
|
|
||||||
draw_rect_tex((texture_t){0}, rgba, start, end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// game ui
|
// game ui
|
||||||
|
|
||||||
|
typedef struct gui_state_t {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
bool held;
|
||||||
|
bool hover;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} gui_state_t;
|
||||||
|
|
||||||
static __thread array(guiskin_t) skins=0;
|
static __thread array(guiskin_t) skins=0;
|
||||||
static __thread guiskin_t *last_skin=0;
|
static __thread guiskin_t *last_skin=0;
|
||||||
static __thread map(int, gui_state_t) ctl_states=0; //@leak
|
static __thread map(int, gui_state_t) ctl_states=0; //@leak
|
||||||
|
@ -11154,15 +11125,13 @@ void *gui_userdata() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
gui_state_t *gui_getstate(int id, int kind) {
|
gui_state_t *gui_getstate(int id) {
|
||||||
if (!ctl_states) map_init(ctl_states, less_int, hash_int);
|
if (!ctl_states) map_init(ctl_states, less_int, hash_int);
|
||||||
static gui_state_t st={0};
|
return map_find_or_add(ctl_states, id, (gui_state_t){0});
|
||||||
st.kind=kind;
|
|
||||||
return map_find_or_add(ctl_states, id, st);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool (gui_button)(int id, vec4 r, const char *skin) {
|
bool (gui_button)(int id, vec4 r, const char *skin) {
|
||||||
gui_state_t *entry = gui_getstate(id, GUI_BUTTON);
|
gui_state_t *entry = gui_getstate(id);
|
||||||
bool was_clicked=0;
|
bool was_clicked=0;
|
||||||
entry->hover = false;
|
entry->hover = false;
|
||||||
|
|
||||||
|
@ -11178,20 +11147,14 @@ bool (gui_button)(int id, vec4 r, const char *skin) {
|
||||||
entry->held = false;
|
entry->held = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_skin->draw_rect_func) last_skin->draw_rect_func(last_skin->userdata, *entry, skin, r);
|
char *btn = va("%s%s", skin?skin:"button", entry->held?"_press":entry->hover?"_hover":"");
|
||||||
else {
|
if (last_skin->draw_rect_func) last_skin->draw_rect_func(last_skin->userdata, btn, r);
|
||||||
draw_rect(entry->held ? 0x111111FF : entry->hover ? 0xEEEEEEFF : 0xFFFFFFFF, v42v2(r));
|
|
||||||
}
|
|
||||||
|
|
||||||
return was_clicked;
|
return was_clicked;
|
||||||
}
|
}
|
||||||
|
|
||||||
void (gui_panel)(int id, vec4 r, const char *skin) {
|
void (gui_panel)(int id, vec4 r, const char *skin) {
|
||||||
gui_state_t *entry = gui_getstate(id, GUI_PANEL);
|
if (last_skin->draw_rect_func) last_skin->draw_rect_func(last_skin->userdata, skin?skin:"panel", r);
|
||||||
if (last_skin->draw_rect_func) last_skin->draw_rect_func(last_skin->userdata, *entry, skin?skin:"panel", r);
|
|
||||||
else {
|
|
||||||
draw_rect(0xFFFFFFFF, v42v2(r));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skinned */
|
/* skinned */
|
||||||
|
@ -11204,26 +11167,23 @@ void skinned_free(void* userdata) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
atlas_slice_frame_t *skinned_getsliceframe(atlas_t *a, const char *name, const char *fallback) {
|
atlas_slice_frame_t *skinned_getsliceframe(atlas_t *a, const char *name) {
|
||||||
#define atlas_loop(n)\
|
for (int i = 0; i < array_count(a->slices); i++)
|
||||||
for (int i = 0; i < array_count(a->slices); i++)\
|
if (!strcmp(quark_string(&a->db, a->slices[i].name), name))
|
||||||
if (!strcmp(quark_string(&a->db, a->slices[i].name), n))\
|
return &a->slice_frames[a->slices[i].frames[0]];
|
||||||
return &a->slice_frames[a->slices[i].frames[0]];
|
|
||||||
atlas_loop(name);
|
|
||||||
atlas_loop(fallback);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
#undef atlas_loop
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void skinned_draw_missing_rect(vec4 r) {
|
void skinned_draw_missing_rect(vec4 r) {
|
||||||
draw_rect_tex(texture_checker(), 0xFFFFFFFF, v42v2(r));
|
vec4 size = vec4(0, 0, texture_checker().w, texture_checker().h);
|
||||||
|
gui_drawrect(texture_checker(), v42v2(size), 0x800080FF, v42v2(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r) {
|
void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r) {
|
||||||
if (!f->has_9slice) {
|
if (!f->has_9slice) {
|
||||||
draw_rect_sheet(a->tex, v42v2(f->bounds), 0xFFFFFFFF, v42v2(r));
|
gui_drawrect(a->tex, v42v2(f->bounds), 0xFFFFFFFF, v42v2(r));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11247,6 +11207,14 @@ void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r
|
||||||
vec4 bottom_middle_slice = {core.x, core.w, core.z, outer.w};
|
vec4 bottom_middle_slice = {core.x, core.w, core.z, outer.w};
|
||||||
vec4 bottom_right_slice = {core.z, core.w, outer.z, outer.w};
|
vec4 bottom_right_slice = {core.z, core.w, outer.z, outer.w};
|
||||||
|
|
||||||
|
// Ensure dest rectangle is large enough to render the whole element
|
||||||
|
if ((r.z-r.x) < (outer.z-outer.x) * scale) {
|
||||||
|
r.z = r.x + (outer.z-outer.x) * scale;
|
||||||
|
}
|
||||||
|
if ((r.w-r.y) < (outer.w-outer.y) * scale) {
|
||||||
|
r.w = r.y + (outer.w-outer.y) * scale;
|
||||||
|
}
|
||||||
|
|
||||||
vec4 top_left = {r.x, r.y, r.x + (core.x - outer.x) * scale, r.y + (core.y - outer.y) * scale};
|
vec4 top_left = {r.x, r.y, r.x + (core.x - outer.x) * scale, r.y + (core.y - outer.y) * scale};
|
||||||
vec4 top_right = {r.z - (outer.z - core.z) * scale, r.y, r.z, r.y + (core.y - outer.y) * scale};
|
vec4 top_right = {r.z - (outer.z - core.z) * scale, r.y, r.z, r.y + (core.y - outer.y) * scale};
|
||||||
vec4 bottom_left = {r.x, r.w - (outer.w - core.w) * scale, r.x + (core.x - outer.x) * scale, r.w};
|
vec4 bottom_left = {r.x, r.w - (outer.w - core.w) * scale, r.x + (core.x - outer.x) * scale, r.w};
|
||||||
|
@ -11259,41 +11227,24 @@ void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r
|
||||||
|
|
||||||
vec4 center = {top_left.z, top_left.w, top_right.x, bottom_right.y};
|
vec4 center = {top_left.z, top_left.w, top_right.x, bottom_right.y};
|
||||||
|
|
||||||
draw_rect_sheet(a->tex, v42v2(center_slice), 0xFFFFFFFF, v42v2(center));
|
gui_drawrect(a->tex, v42v2(center_slice), 0xFFFFFFFF, v42v2(center));
|
||||||
draw_rect_sheet(a->tex, v42v2(top_left_slice), 0xFFFFFFFF, v42v2(top_left));
|
gui_drawrect(a->tex, v42v2(top_left_slice), 0xFFFFFFFF, v42v2(top_left));
|
||||||
draw_rect_sheet(a->tex, v42v2(top_right_slice), 0xFFFFFFFF, v42v2(top_right));
|
gui_drawrect(a->tex, v42v2(top_right_slice), 0xFFFFFFFF, v42v2(top_right));
|
||||||
draw_rect_sheet(a->tex, v42v2(bottom_left_slice), 0xFFFFFFFF, v42v2(bottom_left));
|
gui_drawrect(a->tex, v42v2(bottom_left_slice), 0xFFFFFFFF, v42v2(bottom_left));
|
||||||
draw_rect_sheet(a->tex, v42v2(bottom_right_slice), 0xFFFFFFFF, v42v2(bottom_right));
|
gui_drawrect(a->tex, v42v2(bottom_right_slice), 0xFFFFFFFF, v42v2(bottom_right));
|
||||||
draw_rect_sheet(a->tex, v42v2(top_middle_slice), 0xFFFFFFFF, v42v2(top));
|
gui_drawrect(a->tex, v42v2(top_middle_slice), 0xFFFFFFFF, v42v2(top));
|
||||||
draw_rect_sheet(a->tex, v42v2(bottom_middle_slice), 0xFFFFFFFF, v42v2(bottom));
|
gui_drawrect(a->tex, v42v2(bottom_middle_slice), 0xFFFFFFFF, v42v2(bottom));
|
||||||
draw_rect_sheet(a->tex, v42v2(middle_left_slice), 0xFFFFFFFF, v42v2(left));
|
gui_drawrect(a->tex, v42v2(middle_left_slice), 0xFFFFFFFF, v42v2(left));
|
||||||
draw_rect_sheet(a->tex, v42v2(middle_right_slice), 0xFFFFFFFF, v42v2(right));
|
gui_drawrect(a->tex, v42v2(middle_right_slice), 0xFFFFFFFF, v42v2(right));
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void skinned_draw_rect(void* userdata, gui_state_t state, const char *skin, vec4 r) {
|
void skinned_draw_rect(void* userdata, const char *skin, vec4 r) {
|
||||||
skinned_t *a = C_CAST(skinned_t*, userdata);
|
skinned_t *a = C_CAST(skinned_t*, userdata);
|
||||||
|
|
||||||
switch (state.kind) {
|
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
||||||
case GUI_BUTTON: {
|
if (!f) skinned_draw_missing_rect(r);
|
||||||
char *btn = va("%s%s", skin?skin:a->button, state.held?"_press":state.hover?"_hover":"");
|
else skinned_draw_sprite(a->scale, &a->atlas, f, r);
|
||||||
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, btn, skin?skin:a->button);
|
|
||||||
if (!f) skinned_draw_missing_rect(r);
|
|
||||||
else skinned_draw_sprite(a->scale, &a->atlas, f, r);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case GUI_PANEL: {
|
|
||||||
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin?skin:a->panel, "");
|
|
||||||
if (!f) skinned_draw_missing_rect(r);
|
|
||||||
else skinned_draw_sprite(a->scale, &a->atlas, f, r);
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
void skinned_preset_skins(skinned_t *s) {
|
|
||||||
s->panel = "panel";
|
|
||||||
s->button = "button";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
guiskin_t gui_skinned(const char *inifile, float scale) {
|
guiskin_t gui_skinned(const char *inifile, float scale) {
|
||||||
|
@ -11304,7 +11255,6 @@ guiskin_t gui_skinned(const char *inifile, float scale) {
|
||||||
skin.userdata = a;
|
skin.userdata = a;
|
||||||
skin.draw_rect_func = skinned_draw_rect;
|
skin.draw_rect_func = skinned_draw_rect;
|
||||||
skin.free = skinned_free;
|
skin.free = skinned_free;
|
||||||
skinned_preset_skins(a);
|
|
||||||
return skin;
|
return skin;
|
||||||
}
|
}
|
||||||
#line 0
|
#line 0
|
||||||
|
|
28
engine/v4k.h
28
engine/v4k.h
|
@ -4182,24 +4182,8 @@ API void sprite_setanim(sprite_t *s, unsigned name);
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// game ui
|
// game ui
|
||||||
|
|
||||||
enum {
|
|
||||||
GUI_PANEL,
|
|
||||||
GUI_BUTTON,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct gui_state_t {
|
|
||||||
int kind;
|
|
||||||
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
bool held;
|
|
||||||
bool hover;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
} gui_state_t;
|
|
||||||
|
|
||||||
typedef struct guiskin_t {
|
typedef struct guiskin_t {
|
||||||
void (*draw_rect_func)(void* userdata, gui_state_t state, const char *skin, vec4 rect);
|
void (*draw_rect_func)(void* userdata, const char *skin, vec4 rect);
|
||||||
void (*free)(void* userdata);
|
void (*free)(void* userdata);
|
||||||
void *userdata;
|
void *userdata;
|
||||||
} guiskin_t;
|
} guiskin_t;
|
||||||
|
@ -4215,19 +4199,15 @@ API void gui_popskin();
|
||||||
#define gui_panel(...) gui_panel(__LINE__, __VA_ARGS__)
|
#define gui_panel(...) gui_panel(__LINE__, __VA_ARGS__)
|
||||||
#define gui_button(...) gui_button(__LINE__, __VA_ARGS__)
|
#define gui_button(...) gui_button(__LINE__, __VA_ARGS__)
|
||||||
|
|
||||||
// default skins
|
// default renderers
|
||||||
API guiskin_t gui_skinned(const char *inifile, float scale);
|
|
||||||
|
|
||||||
|
/// skinned
|
||||||
typedef struct skinned_t {
|
typedef struct skinned_t {
|
||||||
atlas_t atlas;
|
atlas_t atlas;
|
||||||
float scale;
|
float scale;
|
||||||
// unsigned framenum;
|
|
||||||
|
|
||||||
//skins
|
|
||||||
char *panel;
|
|
||||||
char *button;
|
|
||||||
} skinned_t;
|
} skinned_t;
|
||||||
|
|
||||||
|
API guiskin_t gui_skinned(const char *inifile, float scale);
|
||||||
#line 0
|
#line 0
|
||||||
|
|
||||||
#line 1 "v4k_system.h"
|
#line 1 "v4k_system.h"
|
||||||
|
|
Loading…
Reference in New Issue