mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-10-03 04:18:09 +03:00
Add a parameter to gfx_draw_glyph() for controlling blending behavior
This adds a new parameter `blend` to `gfx_draw_glyph()`. When `blend` is true, the function performs normal alpha blending (same as `gfx_draw_glyph_to_pmap()`). If `blend` is false, the resulting pixel color will be the text color and the alpha value will be copied from the glyph texture. However, if the alpha value is less than 0.01, the pixel will not be written. If you are drawing on a transparent texture (which will later be blended into another texture), `blend` should be false. If you are drawing on top of an image, `blend` should be true. `gfx_draw_glyph()` used to fill transparent pixels with text color, but this step is no longer needed and has been removed.
This commit is contained in:
+1
-1
@@ -132,7 +132,7 @@ int gfx_get_font_space(void);
|
||||
SDL_Color gfx_get_font_color(void);
|
||||
void gfx_set_font_name(const char *name);
|
||||
|
||||
int gfx_render_text(Texture *dst, float x, int y, char *msg, struct text_style *ts);
|
||||
int gfx_render_text(Texture *dst, float x, int y, char *msg, struct text_style *ts, bool blend);
|
||||
void gfx_draw_text_to_amap(Texture *dst, int x, int y, char *text);
|
||||
void gfx_draw_text_to_pmap(Texture *dst, int x, int y, char *text);
|
||||
float gfx_size_char(struct text_style *ts, const char *ch);
|
||||
|
||||
+1
-1
@@ -170,7 +170,7 @@ void gfx_copy_stretch_with_alpha_map(Texture *dst, int dx, int dy, int dw, int d
|
||||
void gfx_copy_grayscale(Texture *dst, int dx, int dy, Texture *src, int sx, int sy, int w, int h);
|
||||
void gfx_draw_line(Texture *dst, int x0, int y0, int x1, int y1, int r, int g, int b);
|
||||
void gfx_draw_line_to_amap(Texture *dst, int x0, int y0, int x1, int y1, int a);
|
||||
void gfx_draw_glyph(Texture *dst, float dx, int dy, Texture *glyph, SDL_Color color, float scale_x, float bold_width);
|
||||
void gfx_draw_glyph(Texture *dst, float dx, int dy, Texture *glyph, SDL_Color color, float scale_x, float bold_width, bool blend);
|
||||
void gfx_draw_glyph_to_pmap(Texture *dst, float dx, int dy, Texture *glyph, Rectangle glyph_pos, SDL_Color color, float scale_x);
|
||||
void gfx_draw_glyph_to_amap(Texture *dst, float dx, int dy, Texture *glyph, Rectangle glyph_pos, float scale_x);
|
||||
|
||||
|
||||
@@ -15,12 +15,14 @@
|
||||
*/
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform vec4 color;
|
||||
uniform vec4 color; // .a is the discard threshold
|
||||
|
||||
in vec2 tex_coord;
|
||||
out vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
vec4 texel = texture(tex, tex_coord);
|
||||
frag_color = vec4(color.rgb, texel.r * color.a);
|
||||
vec4 texel = texture(tex, tex_coord);
|
||||
if (texel.r < color.a)
|
||||
discard;
|
||||
frag_color = vec4(color.rgb, texel.r);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform float threshold;
|
||||
uniform vec4 color;
|
||||
uniform vec4 color; // .a is the discard threshold
|
||||
|
||||
in vec2 tex_coord;
|
||||
out vec4 frag_color;
|
||||
@@ -43,5 +43,7 @@ void main() {
|
||||
}
|
||||
}
|
||||
|
||||
if (a_out < color.a)
|
||||
discard;
|
||||
frag_color = vec4(color.rgb, min(a_out, 1.0));
|
||||
}
|
||||
|
||||
+11
-17
@@ -1118,29 +1118,23 @@ void gfx_draw_line_to_amap(Texture *dst, int x0, int y0, int x1, int y1, int a)
|
||||
}
|
||||
|
||||
// XXX: Not an actual DrawGraph function; used for rendering text
|
||||
void gfx_draw_glyph(Texture *dst, float dx, int dy, Texture *glyph, SDL_Color color, float scale_x, float bold_width)
|
||||
void gfx_draw_glyph(Texture *dst, float dx, int dy, Texture *glyph, SDL_Color color, float scale_x, float bold_width, bool blend)
|
||||
{
|
||||
if (blend) {
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
|
||||
} else {
|
||||
glBlendFunc(GL_ONE, GL_ZERO);
|
||||
glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
|
||||
}
|
||||
|
||||
dx = roundf(dx);
|
||||
|
||||
glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ZERO, GL_ONE);
|
||||
struct copy_data fill_data = COPY_DATA(dx, dy, dx, dy, glyph->w * scale_x, glyph->h);
|
||||
fill_data.r = color.r / 255.0;
|
||||
fill_data.g = color.g / 255.0;
|
||||
fill_data.b = color.b / 255.0;
|
||||
fill_data.a = 0.0;
|
||||
fill_data.threshold = 0.001;
|
||||
run_copy_shader(&fill_amap_under_border_shader.s, dst, dst, &fill_data);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
|
||||
|
||||
struct copy_data data = STRETCH_DATA(
|
||||
dx, dy, glyph->w * scale_x, glyph->h,
|
||||
0, 0, glyph->w, glyph->h);
|
||||
data.r = color.r / 255.0;
|
||||
data.g = color.g / 255.0;
|
||||
data.b = color.b / 255.0;
|
||||
data.a = 1.0;
|
||||
data.a = 0.01; // discard threshold
|
||||
|
||||
if (bold_width < 0.01) {
|
||||
run_copy_shader(&blend_rmap_color_shader.s, dst, glyph, &data);
|
||||
@@ -1160,7 +1154,7 @@ void gfx_draw_glyph_to_pmap(Texture *dst, float dx, int dy, Texture *glyph, Rect
|
||||
data.r = color.r / 255.0;
|
||||
data.g = color.g / 255.0;
|
||||
data.b = color.b / 255.0;
|
||||
data.a = 1.0;
|
||||
data.a = 0.01; // discard threshold
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
|
||||
run_copy_shader(&blend_rmap_color_shader.s, dst, glyph, &data);
|
||||
restore_blend_mode();
|
||||
@@ -1174,7 +1168,7 @@ void gfx_draw_glyph_to_amap(Texture *dst, float dx, int dy, Texture *glyph, Rect
|
||||
data.r = 1.0;
|
||||
data.g = 1.0;
|
||||
data.b = 1.0;
|
||||
data.a = 1.0;
|
||||
data.a = 0.0; // discard threshold
|
||||
glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_ONE, GL_ZERO);
|
||||
run_copy_shader(&blend_rmap_color_shader.s, dst, glyph, &data);
|
||||
restore_blend_mode();
|
||||
|
||||
@@ -181,7 +181,7 @@ static void charsprite_render(struct charsprite *cs)
|
||||
|
||||
sprite_init_color(&cs->sp, w, h, 0, 0, 0, 0);
|
||||
sprite_get_texture(&cs->sp); // XXX: force initialization of texture
|
||||
gfx_render_text(&cs->sp.texture, 0.0f, 0, ch, &cs->ts);
|
||||
gfx_render_text(&cs->sp.texture, 0.0f, 0, ch, &cs->ts, false);
|
||||
sprite_dirty(&cs->sp);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -529,7 +529,7 @@ static void Gpx2Plus_MsgDraw(int surface, int x, int y)
|
||||
skiplen = strlen(s);
|
||||
}
|
||||
pos.y += line_height - ts.size; // bottom align
|
||||
pos.x += gfx_render_text(dst, pos.x, pos.y, s, &ts);
|
||||
pos.x += gfx_render_text(dst, pos.x, pos.y, s, &ts, true);
|
||||
pos.y -= line_height - ts.size;
|
||||
if (lb)
|
||||
*lb = '<';
|
||||
|
||||
@@ -343,7 +343,7 @@ static float sp_text_draw(struct sact_sprite *sp, struct sr_text_properties *tp,
|
||||
tp->last_char = last_char;
|
||||
|
||||
sprite_dirty(sp);
|
||||
return gfx_render_text(tex, x ,y, text->text, &tp->ts);
|
||||
return gfx_render_text(tex, x ,y, text->text, &tp->ts, false);
|
||||
}
|
||||
|
||||
static void SengokuRanceFont_SP_TextDraw(int sp_no, struct string *text)
|
||||
|
||||
@@ -120,7 +120,7 @@ bool StoatSpriteEngine_SP_SetTextSprite(int sp_no, struct string *text)
|
||||
w /= 2;
|
||||
struct sact_sprite *sp = sact_create_sprite(sp_no, w, h, 0, 0, 0, 0);
|
||||
sprite_get_texture(sp); // XXX: force initialization of texture
|
||||
gfx_render_text(&sp->texture, 0.0f, 0, s, &text_sprite_ts);
|
||||
gfx_render_text(&sp->texture, 0.0f, 0, s, &text_sprite_ts, false);
|
||||
sprite_dirty(sp);
|
||||
return true;
|
||||
}
|
||||
@@ -457,7 +457,7 @@ static bool StoatSpriteEngine_MultiSprite_SetText(int type, int n, struct string
|
||||
int h = ms->ts.size;
|
||||
sprite_init_color(&ms->sp, w, h, 0, 0, 0, 0);
|
||||
sprite_get_texture(&ms->sp); // XXX: force initialization of texture
|
||||
gfx_render_text(&ms->sp.texture, 0.0f, 0, text->text, &ms->ts);
|
||||
gfx_render_text(&ms->sp.texture, 0.0f, 0, text->text, &ms->ts, false);
|
||||
sprite_dirty(&ms->sp);
|
||||
|
||||
ms->cg = 1;
|
||||
|
||||
+3
-3
@@ -161,17 +161,17 @@ static int vmDrawMsg_Draw(int handle)
|
||||
struct vm_surface *sf = vm_surface_get(dm->surfaces[SURFACE_DROP_SHADOW]);
|
||||
int x = dm->pos.x + dm->style.drop_shadow;
|
||||
int y = dm->pos.y + dm->style.drop_shadow;
|
||||
gfx_render_text(&sf->texture, x, y, s, &ts);
|
||||
gfx_render_text(&sf->texture, x, y, s, &ts, false);
|
||||
}
|
||||
if (dm->style.bold) {
|
||||
struct text_style ts = dm->style.ts;
|
||||
ts.bold_width = dm->style.bold;
|
||||
ts.color = dm->style.bold_color;
|
||||
struct vm_surface *sf = vm_surface_get(dm->surfaces[SURFACE_BOLD]);
|
||||
gfx_render_text(&sf->texture, dm->pos.x, dm->pos.y, s, &ts);
|
||||
gfx_render_text(&sf->texture, dm->pos.x, dm->pos.y, s, &ts, false);
|
||||
}
|
||||
struct vm_surface *sf = vm_surface_get(dm->surfaces[SURFACE_TEXT]);
|
||||
dm->pos.x += gfx_render_text(&sf->texture, dm->pos.x, dm->pos.y, s, &dm->style.ts);
|
||||
dm->pos.x += gfx_render_text(&sf->texture, dm->pos.x, dm->pos.y, s, &dm->style.ts, false);
|
||||
if (lb)
|
||||
*lb = '<';
|
||||
} else if (sscanf(s, "<C%d,%d,%d>%n", &a1, &a2, &a3, &skiplen) == 3) {
|
||||
|
||||
@@ -352,7 +352,7 @@ static void build_copy_cut_cg(struct parts_construction_process *cproc, struct p
|
||||
|
||||
static void build_draw_text(struct parts_construction_process *cproc, struct parts_cp_text *op)
|
||||
{
|
||||
gfx_render_text(&cproc->common.texture, op->x, op->y, op->text->text, &op->style);
|
||||
gfx_render_text(&cproc->common.texture, op->x, op->y, op->text->text, &op->style, true);
|
||||
}
|
||||
|
||||
static void build_copy_text(struct parts_construction_process *cproc, struct parts_cp_text *op)
|
||||
@@ -361,7 +361,7 @@ static void build_copy_text(struct parts_construction_process *cproc, struct par
|
||||
int h = ceilf(op->style.size + op->style.edge_up + op->style.edge_down);
|
||||
gfx_fill_with_alpha(&cproc->common.texture, op->x, op->y, w, h,
|
||||
op->style.edge_color.r, op->style.edge_color.g, op->style.edge_color.b, 0);
|
||||
gfx_render_text(&cproc->common.texture, op->x, op->y, op->text->text, &op->style);
|
||||
gfx_render_text(&cproc->common.texture, op->x, op->y, op->text->text, &op->style, false);
|
||||
}
|
||||
|
||||
bool parts_build_construction_process(struct parts *parts,
|
||||
|
||||
+1
-1
@@ -83,7 +83,7 @@ static const char *parts_text_append_char(struct parts_text *t, const char *str)
|
||||
int width = text_style_width(&t->ts, ch->ch);
|
||||
int height = text_style_height(&t->ts);
|
||||
gfx_init_texture_rgba(&ch->t, width, height, (SDL_Color){0,0,0,0});
|
||||
ch->advance = gfx_render_text(&ch->t, 0, 0, ch->ch, &t->ts);
|
||||
ch->advance = gfx_render_text(&ch->t, 0, 0, ch->ch, &t->ts, false);
|
||||
|
||||
line->width += width;
|
||||
line->height = max(line->height, height);
|
||||
|
||||
+2
-8
@@ -372,17 +372,11 @@ void sprite_set_text_pos(struct sact_sprite *sp, int x, int y)
|
||||
void sprite_text_draw(struct sact_sprite *sp, struct string *text, struct text_style *ts)
|
||||
{
|
||||
if (!sp->text.texture.handle) {
|
||||
SDL_Color c;
|
||||
if (text_style_has_edge(ts))
|
||||
c = ts->edge_color;
|
||||
else
|
||||
c = ts->color;
|
||||
c.a = 0;
|
||||
gfx_init_texture_rgba(&sp->text.texture, sp->rect.w, sp->rect.h, c);
|
||||
gfx_init_texture_rgba(&sp->text.texture, sp->rect.w, sp->rect.h, COLOR(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
ts->font_spacing = sp->text.char_space;
|
||||
sp->text.pos.x += gfx_render_text(&sp->text.texture, sp->text.pos.x, sp->text.pos.y, text->text, ts);
|
||||
sp->text.pos.x += gfx_render_text(&sp->text.texture, sp->text.pos.x, sp->text.pos.y, text->text, ts, false);
|
||||
if (sp->text.current_line_height < ts->size)
|
||||
sp->text.current_line_height = ts->size;
|
||||
sprite_dirty(sp);
|
||||
|
||||
+12
-5
@@ -201,6 +201,7 @@ float gfx_get_actual_font_size_round_down(unsigned face, float size)
|
||||
}
|
||||
|
||||
enum text_render_mode {
|
||||
RENDER_COPY,
|
||||
RENDER_BLENDED,
|
||||
RENDER_PMAP,
|
||||
RENDER_AMAP,
|
||||
@@ -237,10 +238,14 @@ static int render_text(Texture *dst, char *msg, struct text_render_metrics *tm)
|
||||
|
||||
// render glyph
|
||||
Texture *t = &glyph->t[tm->weight];
|
||||
if (tm->mode == RENDER_BLENDED) {
|
||||
if (tm->mode == RENDER_COPY) {
|
||||
float x = pos_x - glyph->rect.x;
|
||||
int y = pos_y - glyph->rect.y;
|
||||
gfx_draw_glyph(dst, x, y, t, tm->color, config.text_x_scale, tm->edge_width);
|
||||
gfx_draw_glyph(dst, x, y, t, tm->color, config.text_x_scale, tm->edge_width, false);
|
||||
} else if (tm->mode == RENDER_BLENDED) {
|
||||
float x = pos_x - glyph->rect.x;
|
||||
int y = pos_y - glyph->rect.y;
|
||||
gfx_draw_glyph(dst, x, y, t, tm->color, config.text_x_scale, tm->edge_width, true);
|
||||
} else if (tm->mode == RENDER_PMAP) {
|
||||
gfx_draw_glyph_to_pmap(dst, pos_x, pos_y, t, glyph->rect, tm->color, config.text_x_scale);
|
||||
} else if (tm->mode == RENDER_AMAP) {
|
||||
@@ -271,11 +276,12 @@ static enum font_weight int_to_font_weight(int weight)
|
||||
return (weight % 1000) < 551 ? FONT_WEIGHT_BOLD : FONT_WEIGHT_HEAVY;
|
||||
}
|
||||
|
||||
int gfx_render_text(Texture *dst, float x, int y, char *msg, struct text_style *ts)
|
||||
int gfx_render_text(Texture *dst, float x, int y, char *msg, struct text_style *ts, bool blend)
|
||||
{
|
||||
enum font_weight weight = int_to_font_weight(ts->weight);
|
||||
struct font_size *font_size = text_style_font_size(ts);
|
||||
float edge_width = text_style_edge_width(ts);
|
||||
enum text_render_mode mode = blend ? RENDER_BLENDED : RENDER_COPY;
|
||||
if (edge_width > 0.01f) {
|
||||
struct text_render_metrics metrics = {
|
||||
.x = x,
|
||||
@@ -287,10 +293,11 @@ int gfx_render_text(Texture *dst, float x, int y, char *msg, struct text_style *
|
||||
.space_scale_x = ts->space_scale_x,
|
||||
.font_spacing = ts->font_spacing,
|
||||
.edge_spacing = gfx_text_advance_edges ? edge_width : 0.0,
|
||||
.mode = RENDER_BLENDED,
|
||||
.mode = mode,
|
||||
.font_size = font_size,
|
||||
};
|
||||
render_text(dst, msg, &metrics);
|
||||
mode = RENDER_BLENDED; // core text is blended on top of the edge
|
||||
}
|
||||
struct text_render_metrics metrics = {
|
||||
.x = x,
|
||||
@@ -302,7 +309,7 @@ int gfx_render_text(Texture *dst, float x, int y, char *msg, struct text_style *
|
||||
.space_scale_x = ts->space_scale_x,
|
||||
.font_spacing = ts->font_spacing,
|
||||
.edge_spacing = gfx_text_advance_edges ? edge_width : 0.0,
|
||||
.mode = RENDER_BLENDED,
|
||||
.mode = mode,
|
||||
.font_size = font_size,
|
||||
};
|
||||
return render_text(dst, msg, &metrics);
|
||||
|
||||
Reference in New Issue
Block a user