mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-22 20:41:20 +00:00
[renderer] Replace Draw_FontString with Draw_Glyph
While Draw_Glyph does draw only one glyph at a time, it doesn't shape the text every time, so is a major win for performance (especially coupled with pre-shaped text).
This commit is contained in:
parent
d98eb8abc6
commit
5668006087
13 changed files with 86 additions and 158 deletions
|
@ -59,7 +59,7 @@ void gl_Draw_Picf (float x, float y, struct qpic_s *pic);
|
|||
void gl_Draw_SubPic(int x, int y, struct qpic_s *pic,
|
||||
int srcx, int srcy, int width, int height);
|
||||
int gl_Draw_AddFont (struct font_s *font);
|
||||
void gl_Draw_FontString (int x, int y, int fontid, const char *str);
|
||||
void gl_Draw_Glyph (int x, int y, int fontid, int glyphid, int c);
|
||||
|
||||
void GL_Set2D (void);
|
||||
void GL_Set2DScaled (void);
|
||||
|
|
|
@ -60,7 +60,7 @@ void glsl_Draw_Picf (float x, float y, struct qpic_s *pic);
|
|||
void glsl_Draw_SubPic(int x, int y, struct qpic_s *pic,
|
||||
int srcx, int srcy, int width, int height);
|
||||
int glsl_Draw_AddFont (struct font_s *font);
|
||||
void glsl_Draw_FontString (int x, int y, int fontid, const char *str);
|
||||
void glsl_Draw_Glyph (int x, int y, int fontid, int glyphid, int c);
|
||||
|
||||
void GLSL_Set2D (void);
|
||||
void GLSL_Set2DScaled (void);
|
||||
|
|
|
@ -82,8 +82,8 @@ void Vulkan_Draw_SubPic(int x, int y, struct qpic_s *pic,
|
|||
int srcx, int srcy, int width, int height,
|
||||
struct vulkan_ctx_s *ctx);
|
||||
int Vulkan_Draw_AddFont (struct font_s *font, struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Draw_FontString (int x, int y, int fontid, const char *str,
|
||||
struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Draw_Glyph (int x, int y, int fontid, int glyphid, int c,
|
||||
struct vulkan_ctx_s *ctx);
|
||||
|
||||
void Vulkan_Set2D (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Set2DScaled (struct vulkan_ctx_s *ctx);
|
||||
|
|
|
@ -269,7 +269,7 @@ void Draw_SubPic(int x, int y, qpic_t *pic, int srcx, int srcy, int width, int h
|
|||
|
||||
struct font_s;
|
||||
int Draw_AddFont (struct font_s *font);
|
||||
void Draw_FontString (int x, int y, int fontid, const char *str);
|
||||
void Draw_Glyph (int x, int y, int fontid, int glyphid, int c);
|
||||
|
||||
///@}
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ typedef struct vid_render_funcs_s {
|
|||
void (*Draw_Picf) (float x, float y, qpic_t *pic);
|
||||
void (*Draw_SubPic) (int x, int y, qpic_t *pic, int srcx, int srcy, int width, int height);
|
||||
int (*Draw_AddFont) (struct font_s *font);
|
||||
void (*Draw_FontString) (int x, int y, int fontid, const char *str);
|
||||
void (*Draw_Glyph) (int x, int y, int fontid, int glyphid, int c);
|
||||
|
||||
|
||||
struct psystem_s *(*ParticleSystem) (void);
|
||||
|
|
|
@ -1075,17 +1075,15 @@ gl_Draw_AddFont (font_t *rfont)
|
|||
font->texid = GL_LoadTex ("", 0, &tex);
|
||||
return fontid;
|
||||
}
|
||||
#if 0
|
||||
typedef struct {
|
||||
int fontid;
|
||||
byte color[4];
|
||||
} glrgctx_t;
|
||||
|
||||
static void
|
||||
gl_render_glyph (uint32_t glyphid, int x, int y, void *_rgctx)
|
||||
void
|
||||
gl_Draw_Glyph (int x, int y, int fontid, int glyphid, int c)
|
||||
{
|
||||
glrgctx_t *rgctx = _rgctx;
|
||||
glfont_t *font = &gl_fonts.a[rgctx->fontid];
|
||||
if (fontid < 0 || (unsigned) fontid > gl_fonts.size) {
|
||||
return;
|
||||
}
|
||||
|
||||
glfont_t *font = &gl_fonts.a[fontid];
|
||||
font_t *rfont = font->font;
|
||||
vrect_t *rect = &rfont->glyph_rects[glyphid];
|
||||
|
||||
|
@ -1095,7 +1093,12 @@ gl_render_glyph (uint32_t glyphid, int x, int y, void *_rgctx)
|
|||
float v = rect->y;
|
||||
float s = 1.0 / rfont->scrap.width;
|
||||
float t = 1.0 / rfont->scrap.height;
|
||||
qfglColor4ubv (rgctx->color);
|
||||
|
||||
qfglBindTexture (GL_TEXTURE_2D, gl_fonts.a[fontid].texid);
|
||||
qfglBegin (GL_QUADS);
|
||||
|
||||
byte color[4] = { VectorExpand (vid.palette + c * 3), 255 };
|
||||
qfglColor4ubv (color);
|
||||
qfglTexCoord2f (u * s, v * t);
|
||||
qfglVertex2f (x, y);
|
||||
qfglTexCoord2f ((u + w) * s, v * t);
|
||||
|
@ -1104,35 +1107,7 @@ gl_render_glyph (uint32_t glyphid, int x, int y, void *_rgctx)
|
|||
qfglVertex2f (x + w, y + h);
|
||||
qfglTexCoord2f (u * s, (v + h) * t);
|
||||
qfglVertex2f (x, y + h);
|
||||
}
|
||||
#endif
|
||||
void
|
||||
gl_Draw_FontString (int x, int y, int fontid, const char *str)
|
||||
{
|
||||
#if 0
|
||||
if (fontid < 0 || (unsigned) fontid > gl_fonts.size) {
|
||||
return;
|
||||
}
|
||||
glrgctx_t rgctx = {
|
||||
.fontid = fontid,
|
||||
.color = { 127, 255, 153, 255 },
|
||||
};
|
||||
//FIXME ewwwwwww
|
||||
rtext_t text = {
|
||||
.text = str,
|
||||
.language = "en",
|
||||
.script = HB_SCRIPT_LATIN,
|
||||
.direction = HB_DIRECTION_LTR,
|
||||
};
|
||||
|
||||
qfglBindTexture (GL_TEXTURE_2D, gl_fonts.a[fontid].texid);
|
||||
qfglBegin (GL_QUADS);
|
||||
|
||||
rshaper_t *shaper = RText_NewShaper (gl_fonts.a[fontid].font);
|
||||
RText_RenderText (shaper, &text, x, y, gl_render_glyph, &rgctx);
|
||||
RText_DeleteShaper (shaper);
|
||||
|
||||
qfglEnd ();
|
||||
qfglColor4ubv (color_white);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -944,8 +944,21 @@ glsl_render_glyph (uint32_t glyphid, int x, int y, void *_rgctx)
|
|||
glslrgctx_t *rgctx = _rgctx;
|
||||
vrect_t *rect = &rgctx->glyph_rects[glyphid];
|
||||
dstring_t *batch = rgctx->batch;
|
||||
int size = 6 * sizeof (drawvert_t);
|
||||
|
||||
}
|
||||
#endif
|
||||
void
|
||||
glsl_Draw_Glyph (int x, int y, int fontid, int glyphid, int c)
|
||||
{
|
||||
if (fontid < 0 || (unsigned) fontid > glsl_fonts.size) {
|
||||
return;
|
||||
}
|
||||
glslfont_t *font = &glsl_fonts.a[fontid];
|
||||
font_t *rfont = font->font;
|
||||
vrect_t *rect = &rfont->glyph_rects[glyphid];
|
||||
|
||||
dstring_t *batch = glyph_queue;
|
||||
int size = 6 * sizeof (drawvert_t);
|
||||
batch->size += size;
|
||||
dstring_adjust (batch);
|
||||
drawvert_t *verts = (drawvert_t *) (batch->str + batch->size - size);
|
||||
|
@ -954,8 +967,8 @@ glsl_render_glyph (uint32_t glyphid, int x, int y, void *_rgctx)
|
|||
float h = rect->height;
|
||||
float u = rect->x;
|
||||
float v = rect->y;
|
||||
float s = 1.0 / rgctx->width;
|
||||
float t = 1.0 / rgctx->height;
|
||||
float s = 1.0 / rfont->scrap.width;
|
||||
float t = 1.0 / rfont->scrap.height;
|
||||
|
||||
verts[0] = (drawvert_t) {
|
||||
.xyst = { x, y, u * s, v * t },
|
||||
|
@ -976,42 +989,14 @@ glsl_render_glyph (uint32_t glyphid, int x, int y, void *_rgctx)
|
|||
.xyst = { x, y + h, u * s, (v + h) * t },
|
||||
};
|
||||
|
||||
QuatCopy (rgctx->color, verts[0].color);
|
||||
QuatCopy (rgctx->color, verts[1].color);
|
||||
QuatCopy (rgctx->color, verts[2].color);
|
||||
QuatCopy (rgctx->color, verts[3].color);
|
||||
QuatCopy (rgctx->color, verts[4].color);
|
||||
QuatCopy (rgctx->color, verts[5].color);
|
||||
}
|
||||
#endif
|
||||
void
|
||||
glsl_Draw_FontString (int x, int y, int fontid, const char *str)
|
||||
{
|
||||
#if 0
|
||||
if (fontid < 0 || (unsigned) fontid > glsl_fonts.size) {
|
||||
return;
|
||||
}
|
||||
glslfont_t *font = &glsl_fonts.a[fontid];
|
||||
font_t *rfont = font->font;
|
||||
glslrgctx_t rgctx = {
|
||||
.glyph_rects = rfont->glyph_rects,
|
||||
.batch = glyph_queue,
|
||||
.width = rfont->scrap.width,
|
||||
.height = rfont->scrap.height,
|
||||
};
|
||||
quat_t color = { 127, 255, 153, 255 };
|
||||
QuatScale (color, 1.0f/255.0f, rgctx.color);
|
||||
//FIXME ewwwwwww
|
||||
rtext_t text = {
|
||||
.text = str,
|
||||
.language = "en",
|
||||
.script = HB_SCRIPT_LATIN,
|
||||
.direction = HB_DIRECTION_LTR,
|
||||
};
|
||||
|
||||
rshaper_t *shaper = RText_NewShaper (rfont);
|
||||
RText_RenderText (shaper, &text, x, y, glsl_render_glyph, &rgctx);
|
||||
RText_DeleteShaper (shaper);
|
||||
quat_t color = { VectorExpand (vid.palette + c * 3), 255 };
|
||||
QuatScale (color, 1.0f/255.0f, color);
|
||||
QuatCopy (color, verts[0].color);
|
||||
QuatCopy (color, verts[1].color);
|
||||
QuatCopy (color, verts[2].color);
|
||||
QuatCopy (color, verts[3].color);
|
||||
QuatCopy (color, verts[4].color);
|
||||
QuatCopy (color, verts[5].color);
|
||||
|
||||
qfeglUseProgram (alpha_2d.program);
|
||||
qfeglEnableVertexAttribArray (alpha_2d.vertex.location);
|
||||
|
@ -1030,5 +1015,4 @@ glsl_Draw_FontString (int x, int y, int fontid, const char *str)
|
|||
glyph_queue->size = 0;
|
||||
qfeglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
qfeglUseProgram (quake_2d.program);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1023,7 +1023,6 @@ static void
|
|||
sw_render_glyph (uint32_t glyphid, int x, int y, void *_rgctx)
|
||||
{
|
||||
swrgctx_t *rgctx = _rgctx;
|
||||
vrect_t *rect = &rgctx->glyph_rects[glyphid];
|
||||
|
||||
float w = rect->width;
|
||||
float h = rect->height;
|
||||
|
@ -1047,30 +1046,32 @@ sw_render_glyph (uint32_t glyphid, int x, int y, void *_rgctx)
|
|||
}
|
||||
#endif
|
||||
void
|
||||
Draw_FontString (int x, int y, int fontid, const char *str)
|
||||
Draw_Glyph (int x, int y, int fontid, int glyphid, int c)
|
||||
{
|
||||
#if 0
|
||||
if (fontid < 0 || (unsigned) fontid > sw_fonts.size) {
|
||||
return;
|
||||
}
|
||||
swfont_t *font = &sw_fonts.a[fontid];
|
||||
font_t *rfont = font->font;
|
||||
swrgctx_t rgctx = {
|
||||
.glyph_rects = rfont->glyph_rects,
|
||||
.bitmap = rfont->scrap_bitmap,
|
||||
.width = rfont->scrap.width,
|
||||
.color = 63,
|
||||
};
|
||||
//FIXME ewwwwwww
|
||||
rtext_t text = {
|
||||
.text = str,
|
||||
.language = "en",
|
||||
.script = HB_SCRIPT_LATIN,
|
||||
.direction = HB_DIRECTION_LTR,
|
||||
};
|
||||
vrect_t *rect = &rfont->glyph_rects[glyphid];
|
||||
int width = rfont->scrap.width;
|
||||
|
||||
rshaper_t *shaper = RText_NewShaper (rfont);
|
||||
RText_RenderText (shaper, &text, x, y, sw_render_glyph, &rgctx);
|
||||
RText_DeleteShaper (shaper);
|
||||
#endif
|
||||
float w = rect->width;
|
||||
float h = rect->height;
|
||||
if (x < 0 || y < 0 || x + w > vid.width || y + h > vid.height) {
|
||||
return;
|
||||
}
|
||||
int u = rect->x;
|
||||
int v = rect->y;
|
||||
byte *src = rfont->scrap_bitmap + v * width + u;
|
||||
byte *dst = d_viewbuffer + y * d_rowbytes + x;
|
||||
while (h-- > 0) {
|
||||
for (int i = 0; i < w; i++) {
|
||||
if (src[i] > 127) {
|
||||
dst[i] = c;
|
||||
}
|
||||
}
|
||||
src += width;
|
||||
dst += d_rowbytes;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -525,7 +525,7 @@ vid_render_funcs_t gl_vid_render_funcs = {
|
|||
.Draw_Picf = gl_Draw_Picf,
|
||||
.Draw_SubPic = gl_Draw_SubPic,
|
||||
.Draw_AddFont = gl_Draw_AddFont,
|
||||
.Draw_FontString = gl_Draw_FontString,
|
||||
.Draw_Glyph = gl_Draw_Glyph,
|
||||
|
||||
.ParticleSystem = gl_ParticleSystem,
|
||||
.R_Init = gl_R_Init,
|
||||
|
|
|
@ -469,7 +469,7 @@ vid_render_funcs_t glsl_vid_render_funcs = {
|
|||
.Draw_Picf = glsl_Draw_Picf,
|
||||
.Draw_SubPic = glsl_Draw_SubPic,
|
||||
.Draw_AddFont = glsl_Draw_AddFont,
|
||||
.Draw_FontString = glsl_Draw_FontString,
|
||||
.Draw_Glyph = glsl_Draw_Glyph,
|
||||
|
||||
.ParticleSystem = glsl_ParticleSystem,
|
||||
.R_Init = glsl_R_Init,
|
||||
|
|
|
@ -482,7 +482,7 @@ vid_render_funcs_t sw_vid_render_funcs = {
|
|||
.Draw_Picf = Draw_Picf,
|
||||
.Draw_SubPic = Draw_SubPic,
|
||||
.Draw_AddFont = Draw_AddFont,
|
||||
.Draw_FontString = Draw_FontString,
|
||||
.Draw_Glyph = Draw_Glyph,
|
||||
|
||||
.ParticleSystem = sw_ParticleSystem,
|
||||
.R_Init = sw_R_Init,
|
||||
|
|
|
@ -291,9 +291,9 @@ vulkan_Draw_AddFont (struct font_s *font)
|
|||
}
|
||||
|
||||
static void
|
||||
vulkan_Draw_FontString (int x, int y, int fontid, const char *str)
|
||||
vulkan_Draw_Glyph (int x, int y, int fontid, int glyphid, int c)
|
||||
{
|
||||
Vulkan_Draw_FontString (x, y, fontid, str, vulkan_ctx);
|
||||
Vulkan_Draw_Glyph (x, y, fontid, glyphid, c, vulkan_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -792,7 +792,7 @@ vid_render_funcs_t vulkan_vid_render_funcs = {
|
|||
.Draw_Picf = vulkan_Draw_Picf,
|
||||
.Draw_SubPic = vulkan_Draw_SubPic,
|
||||
.Draw_AddFont = vulkan_Draw_AddFont,
|
||||
.Draw_FontString = vulkan_Draw_FontString,
|
||||
.Draw_Glyph = vulkan_Draw_Glyph,
|
||||
|
||||
.ParticleSystem = vulkan_ParticleSystem,
|
||||
.R_Init = vulkan_R_Init,
|
||||
|
|
|
@ -1515,65 +1515,33 @@ Vulkan_Draw_AddFont (font_t *rfont, vulkan_ctx_t *ctx)
|
|||
|
||||
return fontid;
|
||||
}
|
||||
#if 0
|
||||
typedef struct {
|
||||
drawframe_t *dframe;
|
||||
descbatch_t *batch;
|
||||
byte color[4];
|
||||
} rgctx_t;
|
||||
|
||||
static void
|
||||
vulkan_render_glyph (uint32_t glyphid, int x, int y, void *_rgctx)
|
||||
void
|
||||
Vulkan_Draw_Glyph (int x, int y, int fontid, int glyph, int c,
|
||||
vulkan_ctx_t *ctx)
|
||||
{
|
||||
rgctx_t *rgctx = _rgctx;
|
||||
glyphqueue_t *queue = &rgctx->dframe->glyph_insts;;
|
||||
drawctx_t *dctx = ctx->draw_context;
|
||||
drawframe_t *dframe = &dctx->frames.a[ctx->curFrame];
|
||||
|
||||
glyphqueue_t *queue = &dframe->glyph_insts;;
|
||||
if (queue->count >= queue->size) {
|
||||
return;
|
||||
}
|
||||
|
||||
rgctx->batch->count++;
|
||||
glyphinst_t *inst = &queue->glyphs[queue->count++];
|
||||
inst->index = glyphid;
|
||||
QuatCopy (rgctx->color, inst->color);
|
||||
inst->position[0] = x;
|
||||
inst->position[1] = y;
|
||||
}
|
||||
#endif
|
||||
void
|
||||
Vulkan_Draw_FontString (int x, int y, int fontid, const char *str,
|
||||
vulkan_ctx_t *ctx)
|
||||
{
|
||||
#if 0
|
||||
drawctx_t *dctx = ctx->draw_context;
|
||||
if (fontid < 0 || (unsigned) fontid > dctx->fonts.size) {
|
||||
return;
|
||||
}
|
||||
drawframe_t *dframe = &dctx->frames.a[ctx->curFrame];
|
||||
|
||||
rgctx_t rgctx = {
|
||||
.dframe = dframe,
|
||||
.color = { 127, 255, 153, 255 },
|
||||
};
|
||||
//FIXME ewwwwwww
|
||||
rtext_t text = {
|
||||
.text = str,
|
||||
.language = "en",
|
||||
.script = HB_SCRIPT_LATIN,
|
||||
.direction = HB_DIRECTION_LTR,
|
||||
};
|
||||
|
||||
rgctx.batch = &dframe->glyph_batch.a[dframe->glyph_batch.size - 1];
|
||||
if (!dframe->glyph_batch.size || rgctx.batch->descid != fontid) {
|
||||
descbatch_t *batch = &dframe->glyph_batch.a[dframe->glyph_batch.size - 1];
|
||||
if (!dframe->glyph_batch.size || batch->descid != fontid) {
|
||||
DARRAY_APPEND(&dframe->glyph_batch,
|
||||
((descbatch_t) { .descid = fontid }));
|
||||
rgctx.batch = &dframe->glyph_batch.a[dframe->glyph_batch.size - 1];
|
||||
batch = &dframe->glyph_batch.a[dframe->glyph_batch.size - 1];
|
||||
}
|
||||
|
||||
rshaper_t *shaper = RText_NewShaper (dctx->fonts.a[fontid].font);
|
||||
RText_RenderText (shaper, &text, x, y, vulkan_render_glyph, &rgctx);
|
||||
RText_DeleteShaper (shaper);
|
||||
#endif
|
||||
batch->count++;
|
||||
glyphinst_t *inst = &queue->glyphs[queue->count++];
|
||||
inst->index = glyph;
|
||||
VectorCopy (vid.palette + c * 3, inst->color);
|
||||
inst->color[3] = 255;
|
||||
inst->position[0] = x;
|
||||
inst->position[1] = y;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue