552 lines
20 KiB
C
552 lines
20 KiB
C
|
|
/*
|
|
void gfx_calc_mono(fchar_t *glyphs, int width, int height) {
|
|
fchar_t *ch;
|
|
for(int z = 0; z < 256; z++) {
|
|
ch = &glyphs[z];
|
|
if(ch->u) {
|
|
ch->s = ch->t = 2;
|
|
ch->u = width - 2;
|
|
ch->v = height - 2;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
byte gfx_font_special(int width, uint ch) {
|
|
return ((ch == CHR_UNK) || (ch == CHR_WSPC)) ? width : ((ch == CHR_SPC) ? (width / 6) : 255);
|
|
}
|
|
|
|
void gfx_calc_font(byte *data, fchar_t *glyphs, int width, int height, int page) {
|
|
int off;
|
|
fchar_t *ch;
|
|
for(int z = 0; z < 256; z++) {
|
|
ch = &glyphs[z];
|
|
if((ch->u = gfx_font_special(width, (page << 8) + z)) != 255) {
|
|
ch->s = ch->t = 0;
|
|
ch->v = ((int)ch->u) * height / width;
|
|
if(((page << 8) + z) != CHR_UNK) {
|
|
for(int x = 0; x < width; x++) {
|
|
for(int y = 0; y < height; y++) {
|
|
off = FONT_STRIDE(x, y, z);
|
|
data[off+3] = 0;
|
|
}
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
ch->s = ch->t = 255;
|
|
ch->u = ch->v = 0;
|
|
for(int x = 0; x < width; x++) {
|
|
for(int y = 0; y < height; y++) {
|
|
off = FONT_STRIDE(x, y, z);
|
|
if(data[off+3]) {
|
|
ch->s = x < ch->s ? x : ch->s;
|
|
ch->t = y < ch->t ? y : ch->t;
|
|
ch->u = x > ch->u ? x : ch->u;
|
|
ch->v = y > ch->v ? y : ch->v;
|
|
}
|
|
}
|
|
}
|
|
if(ch->s == 255 && ch->t == 255 && ch->u == 0 && ch->v == 0) {
|
|
ch->s = ch->t = 0;
|
|
}
|
|
else {
|
|
ch->u += 1;
|
|
ch->v += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
int gfx_load_font(font_t *font, const char *path) {
|
|
byte *data;
|
|
int width, height;
|
|
int pages = 0;
|
|
font->xglyph = 0;
|
|
// if(mono)
|
|
// mono->xglyph = 0;
|
|
for(int page = 0; page < UNI_MAX_PAGES; page++) {
|
|
sprintf(sys.work_buf, "fonts/%s_%04x.png", path, page);
|
|
if(!(data = img_load(sys.work_buf, &width, &height, 0, 1))) {
|
|
if(!page) {
|
|
|
|
return 0;
|
|
}
|
|
font->textures[page] = 0;
|
|
font->sizes[page] = NULL;
|
|
// if(mono) {
|
|
// mono->textures[page] = 0;
|
|
// mono->sizes[page] = NULL;
|
|
// }
|
|
continue;
|
|
}
|
|
if(page == 0) {
|
|
if(width > 3968 || height > 3968) {
|
|
|
|
mem_free(data);
|
|
return 0;
|
|
}
|
|
else if((width % 16) || (height % 16)) {
|
|
|
|
mem_free(data);
|
|
return 0;
|
|
}
|
|
font->xsize = width;
|
|
font->ysize = height;
|
|
font->xglyph = width >> 4;
|
|
font->yglyph = height >> 4;
|
|
}
|
|
else if(font->xsize != width || font->ysize != height) {
|
|
|
|
font->textures[page] = 0;
|
|
font->sizes[page] = NULL;
|
|
// if(mono) {
|
|
// mono->textures[page] = 0;
|
|
// mono->sizes[page] = NULL;
|
|
// }
|
|
mem_free(data);
|
|
continue;
|
|
}
|
|
pages += 1;
|
|
font->sizes[page] = mem_alloc(256 * sizeof(fchar_t), MEM_FONT);
|
|
gfx_calc_font(data, font->sizes[page], font->xglyph, font->yglyph, page);
|
|
tex_push(&font->textures[page], data, width, height);
|
|
// if(mono) {
|
|
// mono->sizes[page] = mem_alloc(256 * sizeof(fchar_t), MEM_FONT);
|
|
// memcpy(mono->sizes[page], font->sizes[page], 256 * sizeof(fchar_t));
|
|
// gfx_calc_mono(mono->sizes[page], font->xglyph, font->yglyph);
|
|
// mono->textures[page] = font->textures[page];
|
|
// }
|
|
logd(LOG_GFX, STR_TEX_ILOADED, sys.work_buf, font->textures[page]);
|
|
mem_free(data);
|
|
}
|
|
// if(mono) {
|
|
// mono->xsize = font->xsize;
|
|
// mono->ysize = font->ysize;
|
|
// mono->xglyph = font->xglyph;
|
|
// mono->yglyph = font->yglyph;
|
|
// }
|
|
return pages;
|
|
}
|
|
|
|
/*
|
|
int gfx_load_font_int(font_t *font, const byte **fdata, const byte **fsizes) {
|
|
int pages = 0;
|
|
byte *data = mem_alloc(12 * 16 * 18 * 16 * 4, MEM_IMAGE);
|
|
font->xglyph = 12;
|
|
font->yglyph = 18;
|
|
font->xsize = 12 * 16;
|
|
font->ysize = 18 * 16;
|
|
for(int page = 0; page < UNI_MAX_PAGES; page++) {
|
|
sprintf(sys.work_buf, "font_%04x", page);
|
|
if(!fdata[page]) {
|
|
font->textures[page] = 0;
|
|
font->sizes[page] = NULL;
|
|
continue;
|
|
}
|
|
pages += 1;
|
|
font->sizes[page] = (fchar_t *)fsizes[page];
|
|
tex_unpack_1bit(data, fdata[page], 12 * 16 * 18 * 16);
|
|
tex_push(&font->textures[page], data, 12 * 16, 18 * 16);
|
|
// mono->sizes[page] = mem_alloc(256 * sizeof(fchar_t), MEM_FONT);
|
|
// memcpy(mono->sizes[page], fsizes[page], 256 * sizeof(fchar_t));
|
|
// gfx_calc_mono(mono->sizes[page], font->xglyph, font->yglyph);
|
|
// mono->textures[page] = font->textures[page];
|
|
logd(LOG_GFX, STR_TEX_ILOADED, sys.work_buf, font->textures[page]);
|
|
}
|
|
mem_free(data);
|
|
return pages;
|
|
}
|
|
*/
|
|
|
|
void gfx_free_font(font_t *font) {
|
|
for(int page = 0; (page < UNI_MAX_PAGES) && font->xglyph; page++) {
|
|
if(font->sizes[page]) {
|
|
mem_free(font->sizes[page]);
|
|
tex_delete(&font->textures[page]);
|
|
}
|
|
// if(mono && mono->sizes[page])
|
|
// mem_free(mono->sizes[page]);
|
|
}
|
|
}
|
|
|
|
/*
|
|
void gfx_free_font_int(font_t *font) {
|
|
for(int page = 0; page < UNI_MAX_PAGES; page++) {
|
|
if(font->sizes[page])
|
|
tex_delete(&font->textures[page]);
|
|
// if(mono->sizes[page])
|
|
// mem_free(mono->sizes[page]);
|
|
}
|
|
}
|
|
*/
|
|
|
|
void gfx_aux_colors(const uint *colors) {
|
|
memcpy(gdr.aux_colors, colors, sizeof(uint) * 8);
|
|
}
|
|
|
|
void gfx_back_color(uint color) {
|
|
gdr.clear_r = (float)((uint)((color >> 16) & 0xff)) / 255.0f;
|
|
gdr.clear_g = (float)((uint)((color >> 8) & 0xff)) / 255.0f;
|
|
gdr.clear_b = (float)((uint)(color & 0xff)) / 255.0f;
|
|
gdr.clear_a = (float)((uint)((color >> 24) & 0xff)) / 255.0f;
|
|
}
|
|
|
|
void shd_fnc_tex() {
|
|
shd_int("tex", 0);
|
|
}
|
|
|
|
void shd_fnc_world() {
|
|
shd_int("tex", 0);
|
|
glUniformBlockBinding(gdr.shader, glGetUniformBlockIndex(gdr.shader, "light_block"), 0);
|
|
}
|
|
|
|
void gfx_view(camera_t *cam, mat4 mat, float x, float y, float z) {
|
|
vec3 pos;
|
|
vec3 center;
|
|
VEC3_SET(pos, x, y, z);
|
|
glm_vec3_add(pos, cam->front, center);
|
|
glm_mat4_identity(mat);
|
|
glm_lookat(pos, center, cam->up, mat);
|
|
}
|
|
|
|
void gfx_perspective(camera_t *cam, mat4 mat) {
|
|
glm_mat4_identity(mat);
|
|
glm_perspective(glm_rad(gdr.fov - (cam->zoom * (gdr.fov - 1.0f))), ((float)wcf.current->frame_x) / ((float)wcf.current->frame_y), gdr.clip_near, gdr.clip_far, mat);
|
|
}
|
|
|
|
void shd_pass_rect(void *u) {
|
|
// shd_sel(gdr.shd_rect);
|
|
shd_vec2v("screen", (float)wcf.current->fb_x, (float)wcf.current->fb_y);
|
|
glBindVertexArray(gdr.vao_quad);
|
|
glActiveTexture(GL_TEXTURE0);
|
|
}
|
|
|
|
void shd_pass_text(void *u) {
|
|
// shd_sel(gdr.shd_text);
|
|
shd_vec2v("screen", (float)wcf.current->fb_x, (float)wcf.current->fb_y);
|
|
shd_float("time", tmr_ftime());
|
|
glBindVertexArray(gdr.vao_quad);
|
|
glActiveTexture(GL_TEXTURE0);
|
|
}
|
|
|
|
void shd_pass_blit(void *u) {
|
|
// shd_sel(gdr.shd_blit);
|
|
glBindVertexArray(gdr.vao_quad);
|
|
glActiveTexture(GL_TEXTURE0);
|
|
}
|
|
|
|
void shd_pass_world(world_t *world) {
|
|
mat4 mat;
|
|
// shd_sel(gdr.shd_world);
|
|
shd_float("clip_near", gdr.clip_near);
|
|
shd_float("clip_far", gdr.clip_far);
|
|
shd_vec2v("screen", (float)wcf.current->frame_x, (float)wcf.current->frame_y);
|
|
// shd_vec3v("world_size", (float)(TEMP_LM_SIZE * CHUNK_SIZE), (float)(TEMP_LM_SIZE * CHUNK_SIZE), (float)(TEMP_LM_SIZE * CHUNK_SIZE));
|
|
shd_vec3v("cam_pos", world->camera.pos_x, world->camera.pos_y, world->camera.pos_z);
|
|
gfx_view(&world->camera, mat, world->camera.pos_x, world->camera.pos_y, world->camera.pos_z);
|
|
shd_mat4("view", mat);
|
|
gfx_perspective(&world->camera, mat);
|
|
shd_mat4("projection", mat);
|
|
/*
|
|
glm_mat4_identity(mat);
|
|
vec3 v;
|
|
VEC3_SET(v, 100.0f, 0.5f, 100.0f);
|
|
glm_scale(mat, v);
|
|
VEC3_SET(v, 0.0f, -1.0f, 0.0f);
|
|
glm_translate(mat, v);
|
|
shd_mat4("model", mat);
|
|
shd_scolor("specular", 0xffffff);
|
|
shd_float("shine", 4.0f);
|
|
*/
|
|
shd_vec3v("dir_direction", gdr.ambient_x, gdr.ambient_y, gdr.ambient_z);
|
|
// shd_vec3v("dir_ambient", 0.1f, 0.1f, 0.2f);
|
|
shd_vec3v("dir_ambient", gdr.clear_r, gdr.clear_g, gdr.clear_b);
|
|
shd_vec3v("dir_diffuse", gdr.clear_r * 1.25f, gdr.clear_g * 1.25f, gdr.clear_b * 1.25f);
|
|
shd_vec3v("dir_specular", gdr.clear_r * 1.5f, gdr.clear_g * 1.5f, gdr.clear_b * 1.5f);
|
|
shd_float("light_factor", gdr.light_blend);
|
|
shd_float("max_vert_dist", gdr.light_dist_vert);
|
|
shd_float("max_cam_dist", gdr.light_dist_cam);
|
|
// shd_float("time", tmr_ftime());
|
|
// glBindVertexArray(gdr.vao_box);
|
|
// glActiveTexture(GL_TEXTURE1);
|
|
// glBindTexture(GL_TEXTURE_2D, gdr.fbtex_lightmap);
|
|
shd_int("n_lights", world->s_lights);
|
|
glActiveTexture(GL_TEXTURE0);
|
|
|
|
glBindBufferBase(GL_UNIFORM_BUFFER, 0, world->light_buf);
|
|
}
|
|
|
|
void shd_pass_vis(world_t *world) {
|
|
mat4 mat;
|
|
gfx_view(&world->camera, mat, world->camera.pos_x, world->camera.pos_y, world->camera.pos_z);
|
|
shd_mat4("view", mat);
|
|
gfx_perspective(&world->camera, mat);
|
|
shd_mat4("projection", mat);
|
|
}
|
|
|
|
void shd_pass_grid(world_t *world) {
|
|
mat4 mat;
|
|
// shd_sel(gdr.shd_vis);
|
|
shd_float("clip_near", gdr.clip_near);
|
|
shd_float("clip_far", gdr.clip_far);
|
|
shd_vec2v("screen", (float)wcf.current->frame_x, (float)wcf.current->frame_y);
|
|
gfx_view(&world->camera, mat, world->camera.pos_x, world->camera.pos_y, world->camera.pos_z);
|
|
shd_mat4("view", mat);
|
|
gfx_perspective(&world->camera, mat);
|
|
shd_mat4("projection", mat);
|
|
shd_float("time", tmr_ftime());
|
|
// glActiveTexture(GL_TEXTURE0);
|
|
}
|
|
|
|
byte gfx_init() {
|
|
gdr.aniso_max = 1.0f;
|
|
// if(gdr.aniso_avail = (GL_API_4_6 || gl_has_ext("GL_EXT_texture_filter_anisotropic") || gl_has_ext("GL_ARB_texture_filter_anisotropic")))
|
|
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &gdr.aniso_max);
|
|
tbl_init(&gdr.textures, 256, 64, sizeof(tex_t), MEM_DRAW);
|
|
tbl_init(&gdr.buffers, 1024, 16, sizeof(buf_t), MEM_DRAW);
|
|
tbl_init(&gdr.shaders, 1, 16, sizeof(shd_t), MEM_DRAW);
|
|
tbl_init(&gdr.framebufs, 1, 16, sizeof(fbo_t), MEM_DRAW);
|
|
tbl_init(&gdr.drawlists, 1, 16384, sizeof(drawlist_t), MEM_DRAW);
|
|
tbl_init(&gdr.materials, 16, 32, sizeof(material_t), MEM_DRAW);
|
|
shd_setvars();
|
|
LOAD_SHADER(text, shd_fnc_tex, shd_pass_text);
|
|
LOAD_SHADER(rect, shd_fnc_tex, shd_pass_rect);
|
|
LOAD_SHADER(blit, shd_fnc_tex, shd_pass_blit);
|
|
LOAD_SHADER(world, shd_fnc_world, shd_pass_world);
|
|
// LOAD_SHADER(lightmap, NULL, NULL);
|
|
LOAD_SHADER(vis, NULL, shd_pass_vis);
|
|
LOAD_SHADER(grid, NULL, shd_pass_grid);
|
|
sys.font_pages = gfx_load_font(&sys.font, "font");
|
|
buf_init_sys(&gdr.vbo_quad, &gdr.vao_quad, vert_quad, sizeof(vert_quad), 2, 2);
|
|
if(!fb_init_sys(&sys.console->fb_gui, &sys.console->fbtex_gui))
|
|
return 0;
|
|
tex_gen_fallback(&gdr.tex_fallback, 8);
|
|
gfx_aux_colors(aux_colors);
|
|
// gfx_back_color(0x000000);
|
|
// gfx_back_color(0xff20208f);
|
|
gfx_back_color(0xff000000);
|
|
// gui_style_default(&sys.style);
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
// gdr.buf_lightmap = buf_init(1, &gdr.vbo_lightmap, &gdr.vao_lightmap, NULL, 0, 2, 2);
|
|
// gdr.fbt_lightmap = fb_init(&gdr.fb_lightmap, &gdr.fbtex_lightmap, NULL, 0, 1);
|
|
// gfx_init_world();
|
|
return 1;
|
|
}
|
|
|
|
void gfx_end() {
|
|
tex_clear();
|
|
buf_clear();
|
|
shd_clear();
|
|
fb_clear();
|
|
gfx_free_font(&sys.font);
|
|
tex_delete(&gdr.tex_fallback);
|
|
buf_delete(&gdr.vbo_quad, &gdr.vao_quad);
|
|
// shd_delete(&gdr.shd_rect);
|
|
// shd_delete(&gdr.shd_text);
|
|
// shd_delete(&gdr.shd_blit);
|
|
// shd_clearall();
|
|
// fb_delete(&sys.console->fb_gui, &sys.console->fbtex_gui);
|
|
tbl_clear(&gdr.textures);
|
|
tbl_clear(&gdr.buffers);
|
|
tbl_clear(&gdr.shaders);
|
|
tbl_clear(&gdr.framebufs);
|
|
tbl_clear(&gdr.drawlists);
|
|
tbl_clear(&gdr.materials);
|
|
}
|
|
|
|
void gfx_blit(uint tex) {
|
|
shd_sel(gdr.shd_blit, NULL);
|
|
glBindTexture(GL_TEXTURE_2D, tex);
|
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
}
|
|
|
|
void gfx_draw_rect(int x, int y, int w, int h, int border, uint tex, uint top, uint bottom, uint b_top, uint b_bottom) {
|
|
shd_sel(gdr.shd_rect, NULL);
|
|
shd_vec2v("offset", (float)x, (float)y);
|
|
shd_vec2v("size", (float)w, (float)h);
|
|
shd_bool("use_tex", tex ? 1 : 0);
|
|
shd_float("border", (float)border);
|
|
shd_color("fill_t", top);
|
|
shd_color("fill_b", bottom);
|
|
shd_color("border_t", b_top);
|
|
shd_color("border_b", b_bottom);
|
|
if(tex) {
|
|
glBindTexture(GL_TEXTURE_2D, tex);
|
|
}
|
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
}
|
|
|
|
void gfx_draw_gui(window_t *win) {
|
|
int x1, y1, x2, y2;
|
|
gui_t *elem = win->selected;
|
|
if(elem && elem->r_dirty && elem->type == GUI_DROPDOWN_HANDLE && !(elem->visible)) {
|
|
glScissor(elem->pos_x, (win->fb_y - (elem->pos_y + elem->size_y)) < 0 ? 0 : (win->fb_y - (elem->pos_y + elem->size_y)), elem->size_x, elem->size_y);
|
|
glEnable(GL_SCISSOR_TEST);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
glDisable(GL_SCISSOR_TEST);
|
|
elem->r_dirty = elem->t_dirty = 0;
|
|
win->selected = NULL;
|
|
for(int z = 0; z < win->n_elems; z++) {
|
|
if((win->elems[z].pos_y + win->elems[z].size_y) > elem->pos_y && win->elems[z].pos_y < (elem->pos_y + elem->size_y) &&
|
|
(win->elems[z].pos_x + win->elems[z].size_x) > elem->pos_x && win->elems[z].pos_x < (elem->pos_x + elem->size_x) && win->elems[z].visible)
|
|
win->elems[z].r_dirty = 1;
|
|
}
|
|
}
|
|
for(int z = 0; z < win->n_elems; z++) {
|
|
elem = &win->elems[z];
|
|
if(elem->r_dirty || elem->t_dirty) {
|
|
if(win->selected == elem && elem->type == GUI_DROPDOWN_HANDLE && elem->visible)
|
|
continue;
|
|
glScissor(elem->pos_x, (win->fb_y - (elem->pos_y + elem->size_y)) < 0 ? 0 : (win->fb_y - (elem->pos_y + elem->size_y)), elem->size_x, elem->size_y);
|
|
// logd("DBG", "%d @ %d %d -> %d %d", elem->id, elem->pos_x, elem->pos_y, elem->pos_x + elem->size_x, elem->pos_y + elem->size_y);
|
|
glEnable(GL_SCISSOR_TEST);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
if(elem->type == GUI_CUSTOM)
|
|
elem->func(elem, 0);
|
|
glDisable(GL_SCISSOR_TEST);
|
|
if(elem->visible && (elem->type != GUI_CUSTOM))
|
|
gfx_draw_rect(elem->pos_x, elem->pos_y, elem->size_x, elem->size_y, elem->border, elem->texture, elem->color_fill_t, elem->color_fill_b, elem->color_brdr_t, elem->color_brdr_b);
|
|
if(elem->visible && (elem->type == GUI_SLIDER))
|
|
gfx_draw_rect(elem->pos_x + elem->sel_start - (elem->sel_end / 2), elem->pos_y, elem->sel_end, elem->size_y, elem->sel_drag, elem->texture, elem->margin_x1, elem->margin_y1, elem->margin_x2, elem->margin_y2);
|
|
elem->r_dirty = 0;
|
|
elem->t_dirty = elem->visible;
|
|
// logd("DBG", "@ r");
|
|
}
|
|
}
|
|
// gfx_pass_text();
|
|
for(int z = 0; z < win->n_elems; z++) {
|
|
elem = &win->elems[z];
|
|
if(elem->t_dirty && elem->visible) {
|
|
if(win->selected == elem && elem->type == GUI_DROPDOWN_HANDLE)
|
|
continue;
|
|
x1 = elem->pos_x + ((elem->type != GUI_SLIDER) ? elem->margin_x1 : 0);
|
|
y1 = elem->pos_y + ((elem->type != GUI_SLIDER) ? elem->margin_y1 : 0);
|
|
x2 = elem->size_x - ((elem->type != GUI_SLIDER) ? (elem->margin_x1 + elem->margin_x2) : 0);
|
|
y2 = elem->size_y - ((elem->type != GUI_SLIDER) ? (elem->margin_y1 + elem->margin_y2) : 0);
|
|
// if(elem->type == GUI_FIELD) {
|
|
glScissor(x1 < 0 ? 0 : x1, (win->fb_y - (y1 + y2)) < 0 ? 0 : (win->fb_y - (y1 + y2)), x2 < 0 ? 0 : x2, y2 < 0 ? 0 : y2);
|
|
glEnable(GL_SCISSOR_TEST);
|
|
// }
|
|
if(elem->type == GUI_CUSTOM)
|
|
elem->func(elem, 1);
|
|
else
|
|
elem->t_dirty = txt_draw(x1 + (elem->xbreak ? 0 : elem->text_x), y1 + elem->text_y,
|
|
0, elem->font_size * elem->font->yglyph,
|
|
elem->font_size * (elem->font->yglyph + elem->line_space), x1 + elem->text_x, y1 + elem->text_y,
|
|
elem->xbreak ? (elem->pos_x + x2) : 0x7fffffff, 0x7fffffff, elem->color_text, 0x00000000, elem->font, elem->text);
|
|
if(elem->type == GUI_FIELD && elem->sel_start >= 0 && elem->sel_end != elem->sel_start)
|
|
txt_draw_range(elem->sel_start, elem->sel_end, x1 + (elem->xbreak ? 0 : elem->text_x), y1 + elem->text_y, 0, elem->font_size * elem->font->yglyph,
|
|
elem->font_size * elem->font->yglyph, x1 + elem->text_x, y1 + elem->text_y,
|
|
elem->xbreak ? (elem->pos_x + x2) : 0x7fffffff, 0x7fffffff, 0x00000000, sys.style.select, elem->font, elem->text);
|
|
// logd("DBG", "%d @ %d %d -> %d %d", elem->id, x1, y1, elem->pos_x + x2, elem->pos_y + y2);
|
|
// if(elem->type == GUI_FIELD) {
|
|
glDisable(GL_SCISSOR_TEST);
|
|
// glScissor(0, 0, sys.fb_x, sys.fb_y);
|
|
// }
|
|
}
|
|
}
|
|
elem = win->selected;
|
|
if(elem && (elem->r_dirty || elem->t_dirty) && elem->type == GUI_DROPDOWN_HANDLE && elem->visible) {
|
|
// gfx_pass_rect();
|
|
glScissor(elem->pos_x, (win->fb_y - (elem->pos_y + elem->size_y)) < 0 ? 0 : (win->fb_y - (elem->pos_y + elem->size_y)), elem->size_x, elem->size_y);
|
|
glEnable(GL_SCISSOR_TEST);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
glDisable(GL_SCISSOR_TEST);
|
|
gfx_draw_rect(elem->pos_x, elem->pos_y, elem->size_x, elem->size_y, elem->border, elem->texture, elem->color_fill_t, elem->color_fill_b, elem->color_brdr_t, elem->color_brdr_b);
|
|
elem->r_dirty = 0;
|
|
// gfx_pass_text();
|
|
x1 = elem->pos_x + elem->margin_x1;
|
|
y1 = elem->pos_y + elem->margin_y1;
|
|
x2 = elem->size_x - (elem->margin_x1 + elem->margin_x2);
|
|
y2 = elem->size_y - (elem->margin_y1 + elem->margin_y2);
|
|
glScissor(x1 < 0 ? 0 : x1, (win->fb_y - (y1 + y2)) < 0 ? 0 : (win->fb_y - (y1 + y2)), x2 < 0 ? 0 : x2, y2 < 0 ? 0 : y2);
|
|
glEnable(GL_SCISSOR_TEST);
|
|
elem->t_dirty = txt_draw(x1 + elem->text_x, y1 + elem->text_y,
|
|
0, elem->font_size * elem->font->yglyph,
|
|
elem->font_size * (elem->font->yglyph + elem->line_space), x1 + elem->text_x, y1 + elem->text_y,
|
|
0x7fffffff, 0x7fffffff, elem->color_text, 0x00000000, elem->font, elem->text);
|
|
glDisable(GL_SCISSOR_TEST);
|
|
}
|
|
}
|
|
|
|
byte gui_inside(gui_t *elem, int x, int y);
|
|
gui_t *gui_clicked(window_t *win, int x, int y);
|
|
|
|
void gfx_draw_gui_overlay(window_t *win) {
|
|
gui_t *elem;
|
|
if(win->open) {
|
|
elem = win->selected;
|
|
if(win->mouse && elem && elem->enabled && elem->visible && (elem->type != GUI_LABEL) && (elem->type != GUI_FIELD) && (elem->type != GUI_DROPDOWN_HANDLE) && (elem->type != GUI_CUSTOM)) {
|
|
gfx_draw_rect(elem->pos_x, elem->pos_y, elem->size_x, elem->size_y, 0, 0, sys.style.press_top, sys.style.press_btm, 0x00000000, 0x00000000);
|
|
return;
|
|
}
|
|
else if(elem && elem->enabled && elem->visible && (elem->type == GUI_FIELD)) {
|
|
if(elem->value && elem->sel_start >= 0 && elem->sel_end == elem->sel_start && fmodf(tmr_ftime(), 1.0f) < 0.5f) {
|
|
int x1 = elem->pos_x + elem->margin_x1;
|
|
int y1 = elem->pos_y + elem->margin_y1;
|
|
int x2 = elem->size_x - (elem->margin_x1 + elem->margin_x2);
|
|
int y2 = elem->size_y - (elem->margin_y1 + elem->margin_y2);
|
|
glScissor(x1 < 0 ? 0 : x1, (win->fb_y - (y1 + y2)) < 0 ? 0 : (win->fb_y - (y1 + y2)), x2 < 0 ? 0 : x2, y2 < 0 ? 0 : y2);
|
|
glEnable(GL_SCISSOR_TEST);
|
|
gfx_draw_rect(elem->min, elem->max, elem->font_size, elem->font->yglyph * elem->font_size, 0, 0, sys.style.cursor, sys.style.cursor, 0x00000000, 0x00000000);
|
|
glDisable(GL_SCISSOR_TEST);
|
|
}
|
|
}
|
|
elem = gui_clicked(win, win->mouse_x, win->mouse_y);
|
|
if(elem && elem->enabled && elem->visible && (elem->type != GUI_LABEL) && /* ( */ (elem->type != GUI_FIELD) && (elem->type != GUI_CUSTOM) /* || (elem != gui.selected)) */ ) {
|
|
if(elem->type == GUI_DROPDOWN_HANDLE) {
|
|
int m = ((win->mouse_y - (elem->pos_y + elem->margin_y1)) * elem->max / (elem->size_y - (elem->margin_y1 + elem->margin_y2)));
|
|
// if((sys.mouse_y - elem->pos_y) < (elem->size_y - elem->margin_y2))
|
|
gfx_draw_rect(elem->pos_x + elem->margin_x1, elem->pos_y + elem->margin_y1 + CLAMP_VALUE(m, 0, elem->max - 1) * ((elem->size_y - (elem->margin_y1 + elem->margin_y2)) / elem->max),
|
|
elem->size_x - (elem->margin_x1 + elem->margin_x2),
|
|
(elem->size_y - (elem->margin_y1 + elem->margin_y2)) / elem->max, 0, 0, sys.style.hover_top, sys.style.hover_btm, 0x00000000, 0x00000000);
|
|
}
|
|
else {
|
|
gfx_draw_rect(elem->pos_x, elem->pos_y, elem->size_x, elem->size_y, 0, 0, sys.style.hover_top, sys.style.hover_btm, 0x00000000, 0x00000000);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void gfx_draw_con_overlay(window_t *win) {
|
|
if(sys.hud_size) {
|
|
conmsg_t *con;
|
|
ulong fade = 1000ULL * (ulong)(sys.hud_fadeout);
|
|
font_t *font = &sys.font;
|
|
int y = sys.hud_bottom ? (win->frame_y - font->yglyph) : 0;
|
|
int pos = sys.hud_pos;
|
|
for(int z = 0; z < sys.hud_size; z++) {
|
|
if(--pos < 0)
|
|
pos = sys.hud_size - 1;
|
|
con = &sys.hud_msgs[pos];
|
|
if(con->message && (con->window == win)) {
|
|
if((sys.tmr_current - con->time) <= fade) {
|
|
txt_draw_range(0, con->length, win->offset_x, win->offset_y + y, 0, font->yglyph, font->yglyph,
|
|
win->offset_x, win->offset_y + y,
|
|
win->offset_x + win->frame_x, win->offset_y + win->frame_y,
|
|
0xffffffff, (uint)sys.hud_opacity << 24, font, con->message);
|
|
y += sys.hud_bottom ? -(font->yglyph) : font->yglyph;
|
|
}
|
|
else {
|
|
con->message = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
material_t *gfx_add_material(uint texture, float density, uint spec_color, float shine, shd_t *shader) {
|
|
material_t *mat = tbl_push(&gdr.materials);
|
|
mat->texture = texture;
|
|
mat->density = density;
|
|
mat->spec_color = spec_color;
|
|
mat->shine = shine;
|
|
mat->shader = shader;
|
|
return mat;
|
|
}
|
|
|
|
void gfx_clear_materials() {
|
|
tbl_clear(&gdr.materials);
|
|
}
|