mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-28 18:50:29 +00:00
(gl_font_renderer_t) Implement basic text block rendering
This commit is contained in:
parent
7dc3b7a9be
commit
8f0302c519
@ -30,6 +30,14 @@
|
||||
|
||||
#define MAX_MSG_LEN_CHUNK 64
|
||||
|
||||
typedef struct gl_raster_block {
|
||||
bool active;
|
||||
bool reuse;
|
||||
bool fullscreen;
|
||||
unsigned allocated;
|
||||
struct gl_coords coords;
|
||||
} gl_raster_block_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gl_t *gl;
|
||||
@ -38,6 +46,8 @@ typedef struct
|
||||
|
||||
const font_renderer_driver_t *font_driver;
|
||||
void *font_data;
|
||||
|
||||
gl_raster_block_t block;
|
||||
} gl_raster_t;
|
||||
|
||||
static void *gl_raster_font_init_font(void *gl_data,
|
||||
@ -156,9 +166,81 @@ static void draw_vertices(gl_t *gl, const struct gl_coords *coords)
|
||||
{
|
||||
gl->shader->set_coords(coords);
|
||||
gl->shader->set_mvp(gl, &gl->mvp_no_rot);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, coords->vertices);
|
||||
}
|
||||
|
||||
static bool realloc_checked(void **ptr, size_t size)
|
||||
{
|
||||
void *nptr;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
if (*ptr)
|
||||
free(*ptr);
|
||||
*ptr = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (*ptr == NULL)
|
||||
nptr = malloc(size);
|
||||
else
|
||||
nptr = realloc(*ptr, size);
|
||||
|
||||
if (nptr)
|
||||
*ptr = nptr;
|
||||
|
||||
return nptr != NULL;
|
||||
}
|
||||
|
||||
static bool resize_block(gl_raster_t *font, unsigned new_size)
|
||||
{
|
||||
gl_raster_block_t *block = &font->block;
|
||||
bool success = false;
|
||||
|
||||
if (!font->block.allocated || new_size > font->block.allocated - 1)
|
||||
{
|
||||
unsigned actual_new_size = next_pow2(new_size);
|
||||
|
||||
bool vsucceeded = realloc_checked((void**)&block->coords.vertex, sizeof(GLfloat) * 2 * actual_new_size);
|
||||
bool csuccceeded = realloc_checked((void**)&block->coords.color, sizeof(GLfloat) * 4 * actual_new_size);
|
||||
bool tsuccceeded = realloc_checked((void**)&block->coords.tex_coord, sizeof(GLfloat) * 2 * actual_new_size);
|
||||
bool lsuccceeded = realloc_checked((void**)&block->coords.lut_tex_coord, sizeof(GLfloat) * 2 * actual_new_size);
|
||||
|
||||
if (vsucceeded && csuccceeded && tsuccceeded && lsuccceeded)
|
||||
{
|
||||
font->block.allocated = actual_new_size;
|
||||
block->coords.vertices = new_size;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
block->coords.vertices = new_size;
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool append_vertices(gl_raster_t *font, const struct gl_coords *coords)
|
||||
{
|
||||
gl_raster_block_t *block = &font->block;
|
||||
unsigned old_size = block->coords.vertices;
|
||||
if (resize_block(font, block->coords.vertices + coords->vertices))
|
||||
{
|
||||
const size_t base_size = coords->vertices * sizeof(GLfloat);
|
||||
memcpy((void*)(block->coords.vertex+old_size*2), coords->vertex, base_size * 2);
|
||||
memcpy((void*)(block->coords.color+old_size*4), coords->color, base_size * 4);
|
||||
memcpy((void*)(block->coords.tex_coord+old_size*2), coords->tex_coord, base_size * 2);
|
||||
memcpy((void*)(block->coords.lut_tex_coord+old_size*2), coords->lut_tex_coord, base_size * 2);
|
||||
}
|
||||
else
|
||||
RARCH_WARN("Allocation failed.");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void render_message(gl_raster_t *font, const char *msg, GLfloat scale,
|
||||
const GLfloat color[4], GLfloat pos_x, GLfloat pos_y, bool align_right)
|
||||
{
|
||||
@ -225,7 +307,10 @@ static void render_message(gl_raster_t *font, const char *msg, GLfloat scale,
|
||||
coords.vertices = 6 * msg_len;
|
||||
coords.lut_tex_coord = gl->coords.lut_tex_coord;
|
||||
|
||||
draw_vertices(gl, &coords);
|
||||
if (font->block.active)
|
||||
append_vertices(font, &coords);
|
||||
else
|
||||
draw_vertices(gl, &coords);
|
||||
|
||||
msg_len_full -= msg_len;
|
||||
msg += msg_len;
|
||||
@ -312,7 +397,10 @@ static void gl_raster_font_render_msg(void *data, const char *msg,
|
||||
drop_mod = 0.3f;
|
||||
}
|
||||
|
||||
setup_viewport(font, full_screen);
|
||||
if (font->block.active)
|
||||
font->block.fullscreen = true;
|
||||
else
|
||||
setup_viewport(font, full_screen);
|
||||
|
||||
if (drop_x || drop_y)
|
||||
{
|
||||
@ -328,7 +416,8 @@ static void gl_raster_font_render_msg(void *data, const char *msg,
|
||||
|
||||
render_message(font, msg, scale, color, x, y, align_right);
|
||||
|
||||
restore_viewport(gl);
|
||||
if (!font->block.active)
|
||||
restore_viewport(gl);
|
||||
}
|
||||
|
||||
static const struct font_glyph *gl_raster_font_get_glyph(
|
||||
@ -341,10 +430,61 @@ static const struct font_glyph *gl_raster_font_get_glyph(
|
||||
return font->font_driver->get_glyph((void*)font->font_driver, code);
|
||||
}
|
||||
|
||||
static void gl_end_block(void *data)
|
||||
{
|
||||
gl_raster_t *font = (gl_raster_t*)data;
|
||||
gl_raster_block_t *block = &font->block;
|
||||
gl_t *gl = font->gl;
|
||||
|
||||
if (block->coords.vertices)
|
||||
{
|
||||
setup_viewport(font, block->fullscreen);
|
||||
|
||||
draw_vertices(gl, &block->coords);
|
||||
|
||||
restore_viewport(gl);
|
||||
}
|
||||
|
||||
if (block->reuse && block->coords.vertices)
|
||||
block->coords.vertices = 0;
|
||||
else
|
||||
{
|
||||
block->active = false;
|
||||
block->allocated = 0;
|
||||
resize_block(font, 0);
|
||||
memset(&block->coords, 0, sizeof(block->coords));
|
||||
}
|
||||
}
|
||||
|
||||
static void gl_begin_block(void *data)
|
||||
{
|
||||
gl_raster_t *font = (gl_raster_t*)data;
|
||||
gl_raster_block_t *block = &font->block;
|
||||
unsigned i = 0;
|
||||
|
||||
if (block->active)
|
||||
{
|
||||
block->reuse = true;
|
||||
gl_end_block(data);
|
||||
}
|
||||
|
||||
block->reuse = false;
|
||||
block->active = true;
|
||||
block->coords.vertices = 0;
|
||||
|
||||
if (!block->allocated)
|
||||
{
|
||||
block->coords.color = block->coords.tex_coord = NULL;
|
||||
block->coords.vertex = block->coords.lut_tex_coord = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
gl_font_renderer_t gl_raster_font = {
|
||||
gl_raster_font_init_font,
|
||||
gl_raster_font_free_font,
|
||||
gl_raster_font_render_msg,
|
||||
"GL raster",
|
||||
gl_raster_font_get_glyph
|
||||
gl_raster_font_get_glyph,
|
||||
gl_begin_block,
|
||||
gl_end_block
|
||||
};
|
||||
|
@ -31,6 +31,8 @@ typedef struct gl_font_renderer
|
||||
const char *ident;
|
||||
|
||||
const struct font_glyph *(*get_glyph)(void *data, uint32_t code);
|
||||
void (*begin_block)(void *data);
|
||||
void (*end_block)(void *data);
|
||||
} gl_font_renderer_t;
|
||||
|
||||
extern gl_font_renderer_t gl_raster_font;
|
||||
|
@ -72,7 +72,7 @@ static void glui_blit_line(gl_t *gl, float x, float y, const char *message, uint
|
||||
{
|
||||
struct font_params params = {0};
|
||||
|
||||
gl_set_viewport(gl, gl->win_width, gl->win_height, false, false);
|
||||
/* gl_set_viewport(gl, gl->win_width, gl->win_height, false, false); */
|
||||
|
||||
params.x = x / gl->win_width;
|
||||
params.y = 1.0f - y / gl->win_height;
|
||||
@ -356,6 +356,9 @@ static void glui_frame(void)
|
||||
|
||||
glui_render_background(settings, gl, glui, false);
|
||||
|
||||
if (gl->font_driver->begin_block)
|
||||
gl->font_driver->begin_block(gl->font_handle);
|
||||
|
||||
menu_list_get_last_stack(menu->menu_list, &dir, &label, &menu_type);
|
||||
|
||||
get_title(label, dir, menu_type, title, sizeof(title));
|
||||
@ -384,17 +387,16 @@ static void glui_frame(void)
|
||||
|
||||
glui_blit_line(gl,
|
||||
glui->margin * 2,
|
||||
glui->margin + glui->term_height * glui->line_height
|
||||
glui->margin + glui->term_height * glui->line_height
|
||||
+ glui->line_height * 2, title_msg, FONT_COLOR_ARGB_TO_RGBA(settings->menu.title_color));
|
||||
}
|
||||
|
||||
|
||||
if (settings->menu.timedate_enable)
|
||||
{
|
||||
disp_timedate_set_label(timedate, sizeof(timedate), 0);
|
||||
glui_blit_line(gl,
|
||||
glui->margin * 14,
|
||||
glui->margin + glui->term_height * glui->line_height
|
||||
glui->margin + glui->term_height * glui->line_height
|
||||
+ glui->line_height * 2, timedate, hover_color);
|
||||
}
|
||||
|
||||
@ -436,7 +438,7 @@ static void glui_frame(void)
|
||||
|
||||
glui_blit_line(gl, x, y, message, selected ? hover_color : normal_color);
|
||||
|
||||
glui_blit_line(gl, gl->win_width - glui->glyph_width * w - glui->margin ,
|
||||
glui_blit_line(gl, gl->win_width - glui->glyph_width * w - glui->margin ,
|
||||
y, type_str_buf, selected ? hover_color : normal_color);
|
||||
}
|
||||
|
||||
@ -458,6 +460,9 @@ static void glui_frame(void)
|
||||
glui->box_message[0] = '\0';
|
||||
}
|
||||
|
||||
if (gl->font_driver->end_block)
|
||||
gl->font_driver->end_block(gl->font_handle);
|
||||
|
||||
if (settings->menu.mouse.enable)
|
||||
glui_draw_cursor(gl, menu->mouse.x, menu->mouse.y);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user