parts: Draw per-character glyphs directly to the screen

Before this, character glyphs were copied to an intermediate texture
(text->common.texture) using gfx_copy_with_alpha_map(). In Daiteikoku,
some text sprites have a character spacing of -4, causing the copy to
cut off the right edge of the previously drawn character.

This fixes the problem by having parts_render_text() blend per-glyph
textures directly onto the target without using an intermediate texture.
This commit is contained in:
kichikuou
2025-02-24 10:07:48 +09:00
parent e9bec3c2fe
commit 81c0c494b0
2 changed files with 21 additions and 31 deletions
+20 -10
View File
@@ -45,15 +45,26 @@ static struct {
GLint multiply_color;
} parts_shader;
static void parts_render_text(struct parts *parts, struct parts_common *common)
static void parts_render_text(struct parts *parts, struct parts_text *t)
{
Rectangle rect = {
.x = parts->global.pos.x + common->origin_offset.x,
.y = parts->global.pos.y + common->origin_offset.y,
.w = common->w,
.h = common->h
};
gfx_render_texture(&parts->states[parts->state].common.texture, &rect);
int x = parts->global.pos.x + t->common.origin_offset.x;
int y = parts->global.pos.y + t->common.origin_offset.y;
for (int i = 0; i < t->nr_lines; i++) {
struct parts_text_line *line = &t->lines[i];
for (int j = 0; j < line->nr_chars; j++) {
struct parts_text_char *ch = &line->chars[j];
Rectangle rect = {
.x = x,
.y = y,
.w = ch->t.w,
.h = ch->t.h
};
gfx_render_texture(&ch->t, &rect);
x += ch->advance;
}
x = parts->global.pos.x + t->common.origin_offset.x;
y += line->height;
}
}
static void parts_render_texture(struct texture *texture, mat4 mw_transform, Rectangle *rect, float blend_rate, vec3 add_color, vec3 multiply_color)
@@ -248,8 +259,7 @@ void parts_render(struct parts *parts)
parts_render_cg(parts, &state->common);
break;
case PARTS_TEXT:
if (state->common.texture.handle)
parts_render_text(parts, &state->common);
parts_render_text(parts, &state->text);
break;
case PARTS_FLASH:
parts_render_flash(parts, &state->flash);
+1 -21
View File
@@ -104,7 +104,7 @@ void parts_text_append(struct parts *parts, struct parts_text *t, struct string
msgp = parts_text_append_char(t, msgp);
}
// calculate required dimensions of texture
// calculate dimensions of the text
float f_width = 0;
int height = 0;
for (int i = 0; i < t->nr_lines; i++) {
@@ -115,26 +115,6 @@ void parts_text_append(struct parts *parts, struct parts_text *t, struct string
if (!width || !height)
return;
// initialize texture
if (t->common.texture.handle)
gfx_delete_texture(&t->common.texture);
gfx_init_texture_rgba(&t->common.texture, width, height, (SDL_Color){0,0,0,0});
// copy glyph textures to main texture
t->cursor.x = 0;
t->cursor.y = 0;
for (int i = 0; i < t->nr_lines; i++) {
struct parts_text_line *line = &t->lines[i];
for (int i = 0; i < line->nr_chars; i++) {
struct parts_text_char *ch = &line->chars[i];
gfx_copy_with_alpha_map(&t->common.texture,
lroundf(t->cursor.x), t->cursor.y,
&ch->t, 0, 0, ch->t.w, ch->t.h);
t->cursor.x += ch->advance;
}
t->cursor.x = 0;
t->cursor.y += line->height;
}
parts_set_dims(parts, &t->common, width, height);
}