X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=gl_draw.c;h=de8bc0850a6b3cc4dafc4bd771053af0873734f1;hb=2c0539f6be0b8edddae93416c0beb38baf4a57ac;hp=b53bebce62e3b4f1679cad4b55967ff9be4fd772;hpb=cd9227cae3c1619c304381491597710ec259d0f5;p=xonotic%2Fdarkplaces.git diff --git a/gl_draw.c b/gl_draw.c index b53bebce..de8bc085 100644 --- a/gl_draw.c +++ b/gl_draw.c @@ -34,6 +34,14 @@ cvar_t r_textshadow = {CVAR_SAVE, "r_textshadow", "0", "draws a shadow on all te cvar_t r_textbrightness = {CVAR_SAVE, "r_textbrightness", "0", "additional brightness for text color codes (0 keeps colors as is, 1 makes them all white)"}; cvar_t r_textcontrast = {CVAR_SAVE, "r_textcontrast", "1", "additional contrast for text color codes (1 keeps colors as is, 0 makes them all black)"}; +cvar_t r_font_postprocess_blur = {CVAR_SAVE, "r_font_postprocess_blur", "0", "font blur amount"}; +cvar_t r_font_postprocess_outline = {CVAR_SAVE, "r_font_postprocess_outline", "0", "font outline amount"}; +cvar_t r_font_postprocess_shadow_x = {CVAR_SAVE, "r_font_postprocess_shadow_x", "0", "font shadow X shift amount, applied during outlining"}; +cvar_t r_font_postprocess_shadow_y = {CVAR_SAVE, "r_font_postprocess_shadow_y", "0", "font shadow Y shift amount, applied during outlining"}; +cvar_t r_font_postprocess_shadow_z = {CVAR_SAVE, "r_font_postprocess_shadow_z", "0", "font shadow Z shift amount, applied during blurring"}; +cvar_t r_font_hinting = {CVAR_SAVE, "r_font_hinting", "3", "0 = no hinting, 1 = light autohinting, 2 = full autohinting, 3 = full hinting"}; +cvar_t r_font_antialias = {CVAR_SAVE, "r_font_antialias", "1", "0 = monochrome, 1 = grey" /* , 2 = rgb, 3 = bgr" */}; + extern cvar_t v_glslgamma; //============================================================================= @@ -347,9 +355,9 @@ cachepic_t *Draw_CachePic_Flags(const char *path, unsigned int cachepicflags) pic->autoload = (cachepicflags & CACHEPICFLAG_NOTPERSISTENT); // load a high quality image from disk if possible - pixels = loadimagepixelsbgra(path, false, true); + pixels = loadimagepixelsbgra(path, false, true, r_texture_convertsRGB_2d.integer); if (pixels == NULL && !strncmp(path, "gfx/", 4)) - pixels = loadimagepixelsbgra(path+4, false, true); + pixels = loadimagepixelsbgra(path+4, false, true, r_texture_convertsRGB_2d.integer); if (pixels) { pic->width = image_width; @@ -435,9 +443,9 @@ rtexture_t *Draw_GetPicTexture(cachepic_t *pic) { if (pic->autoload && !pic->tex) { - pic->tex = loadtextureimage(drawtexturepool, pic->name, false, pic->texflags, true); + pic->tex = loadtextureimage(drawtexturepool, pic->name, false, pic->texflags, true, r_texture_convertsRGB_2d.integer); if (pic->tex == NULL && !strncmp(pic->name, "gfx/", 4)) - pic->tex = loadtextureimage(drawtexturepool, pic->name+4, false, pic->texflags, true); + pic->tex = loadtextureimage(drawtexturepool, pic->name+4, false, pic->texflags, true, r_texture_convertsRGB_2d.integer); if (pic->tex == NULL) pic->tex = draw_generatepic(pic->name, true); } @@ -450,11 +458,9 @@ void Draw_Frame(void) int i; cachepic_t *pic; static double nextpurgetime; - int purgeframe; if (nextpurgetime > realtime) return; nextpurgetime = realtime + 0.05; - purgeframe = draw_frame - 1; for (i = 0, pic = cachepics;i < numcachepics;i++, pic++) { if (pic->autoload && pic->tex && pic->lastusedframe < draw_frame) @@ -532,6 +538,7 @@ void Draw_FreePic(const char *picname) } } +static float snap_to_pixel_x(float x, float roundUpAt); extern int con_linewidth; // to force rewrapping static void LoadFont(qboolean override, const char *name, dp_font_t *fnt) { @@ -542,8 +549,19 @@ static void LoadFont(qboolean override, const char *name, dp_font_t *fnt) fs_offset_t widthbufsize; if(override || !fnt->texpath[0]) + { strlcpy(fnt->texpath, name, sizeof(fnt->texpath)); + // load the cvars when the font is FIRST loaded + fnt->settings.antialias = r_font_antialias.integer; + fnt->settings.hinting = r_font_hinting.integer; + fnt->settings.outline = r_font_postprocess_outline.value; + fnt->settings.blur = r_font_postprocess_blur.value; + fnt->settings.shadowx = r_font_postprocess_shadow_x.value; + fnt->settings.shadowy = r_font_postprocess_shadow_y.value; + fnt->settings.shadowz = r_font_postprocess_shadow_z.value; + } + if(drawtexturepool == NULL) return; // before gl_draw_start, so will be loaded later @@ -615,7 +633,19 @@ static void LoadFont(qboolean override, const char *name, dp_font_t *fnt) case '+': case '-': case '.': - fnt->width_of[ch++] = atof(com_token) + extraspacing; + fnt->width_of[ch] = atof(com_token) + extraspacing; + if (fnt->ft2) + { + for (i = 0; i < MAX_FONT_SIZES; ++i) + { + //Font_MapForIndex(fnt->ft2, i)->width_of[ch] = snap_to_pixel_x(fnt->width_of[ch] * fnt->req_sizes[i], 0.4); + ft2_font_map_t *map = Font_MapForIndex(fnt->ft2, i); + if (!map) + break; + map->width_of[ch] = Font_SnapTo(fnt->width_of[ch], 1/map->size); + } + } + ch++; break; default: if(!strcmp(com_token, "extraspacing")) @@ -782,7 +812,6 @@ static void LoadFont_f(void) for(i = 1; i < MAX_FONT_SIZES; ++i) f->req_sizes[i] = -1; - // for some reason this argc is 3 even when using 2 arguments here, maybe nexuiz screws up if(Cmd_Argc() >= 3) { for(i = 0; i < Cmd_Argc()-3; ++i) @@ -792,6 +821,7 @@ static void LoadFont_f(void) f->req_sizes[i] = sz; } } + LoadFont(true, mainfont, f); } @@ -835,6 +865,13 @@ static void gl_draw_newmap(void) void GL_Draw_Init (void) { int i, j; + Cvar_RegisterVariable(&r_font_postprocess_blur); + Cvar_RegisterVariable(&r_font_postprocess_outline); + Cvar_RegisterVariable(&r_font_postprocess_shadow_x); + Cvar_RegisterVariable(&r_font_postprocess_shadow_y); + Cvar_RegisterVariable(&r_font_postprocess_shadow_z); + Cvar_RegisterVariable(&r_font_hinting); + Cvar_RegisterVariable(&r_font_antialias); Cvar_RegisterVariable(&r_textshadow); Cvar_RegisterVariable(&r_textbrightness); Cvar_RegisterVariable(&r_textcontrast); @@ -853,7 +890,6 @@ void GL_Draw_Init (void) for(i = 0, j = 0; i < MAX_USERFONTS; ++i) if(!FONT_USER[i].title[0]) dpsnprintf(FONT_USER[i].title, sizeof(FONT_USER[i].title), "user%d", j++); - Font_Init(); } void _DrawQ_Setup(void) @@ -1086,12 +1122,14 @@ float DrawQ_TextWidth_UntilWidth_TrackColors_Scale(const char *text, size_t *max size_t bytes_left; ft2_font_map_t *fontmap = NULL; ft2_font_map_t *map = NULL; - ft2_font_map_t *prevmap = NULL; + //ft2_font_map_t *prevmap = NULL; ft2_font_t *ft2 = fnt->ft2; // float ftbase_x; qboolean snap = true; qboolean least_one = false; - float dw, dh; // display w/h + float dw; // display w + //float dh; // display h + const float *width_of; if (!h) h = w; if (!h) { @@ -1111,16 +1149,9 @@ float DrawQ_TextWidth_UntilWidth_TrackColors_Scale(const char *text, size_t *max map_index = Font_IndexForSize(ft2, h, NULL, NULL); fontmap = Font_MapForIndex(ft2, map_index); } - if(snap) - { - if(fabs(sw - 1) > 0.001 || fabs(sh - 1) > 0.001) - snap = false; // turn off pixel snapping for better animation - else - sw = sh = 1; - } dw = w * sw; - dh = h * sh; + //dh = h * sh; if (*maxlen < 1) *maxlen = 1<<30; @@ -1139,6 +1170,14 @@ float DrawQ_TextWidth_UntilWidth_TrackColors_Scale(const char *text, size_t *max maxwidth = -maxwidth; } + //if (snap) + // x = snap_to_pixel_x(x, 0.4); // haha, it's 0 anyway + + if (fontmap) + width_of = fontmap->width_of; + else + width_of = fnt->width_of; + for (i = 0;((bytes_left = *maxlen - (text - text_start)) > 0) && *text;) { size_t i0 = i; @@ -1146,17 +1185,15 @@ float DrawQ_TextWidth_UntilWidth_TrackColors_Scale(const char *text, size_t *max i = text - text_start; if (!ch) break; - if (snap) - x = snap_to_pixel_x(x, 0.4); if (ch == ' ' && !fontmap) { if(!least_one || i0) // never skip the first character - if(x + fnt->width_of[(int) ' '] * dw > maxwidth) + if(x + width_of[(int) ' '] * dw > maxwidth) { i = i0; break; // oops, can't draw this } - x += fnt->width_of[(int) ' '] * dw; + x += width_of[(int) ' '] * dw; continue; } // i points to the char after ^ @@ -1223,14 +1260,14 @@ float DrawQ_TextWidth_UntilWidth_TrackColors_Scale(const char *text, size_t *max map = ft2_oldstyle_map; prevch = 0; if(!least_one || i0) // never skip the first character - if(x + fnt->width_of[ch] * dw > maxwidth) + if(x + width_of[ch] * dw > maxwidth) { i = i0; break; // oops, can't draw this } - x += fnt->width_of[ch] * dw; + x += width_of[ch] * dw; } else { - if (!map || map == ft2_oldstyle_map || map->start < ch || map->start + FONT_CHARS_PER_MAP >= ch) + if (!map || map == ft2_oldstyle_map || ch < map->start || ch >= map->start + FONT_CHARS_PER_MAP) { map = FontMap_FindForChar(fontmap, ch); if (!map) @@ -1245,7 +1282,7 @@ float DrawQ_TextWidth_UntilWidth_TrackColors_Scale(const char *text, size_t *max if (prevch && Font_GetKerningForMap(ft2, map_index, w, h, prevch, ch, &kx, NULL)) x += kx * dw; x += map->glyphs[mapch].advance_x * dw; - prevmap = map; + //prevmap = map; prevch = ch; } } @@ -1273,7 +1310,7 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma Uchar prevch = 0; // used for kerning int tempcolorindex; int map_index = 0; - ft2_font_map_t *prevmap = NULL; // the previous map + //ft2_font_map_t *prevmap = NULL; // the previous map ft2_font_map_t *map = NULL; // the currently used map ft2_font_map_t *fontmap = NULL; // the font map for the size float ftbase_y; @@ -1284,6 +1321,7 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma float pix_x, pix_y; size_t bytes_left; float dw, dh; + const float *width_of; int tw, th; tw = R_TextureWidth(fnt->tex); @@ -1307,13 +1345,6 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma map_index = Font_IndexForSize(ft2, h, NULL, NULL); fontmap = Font_MapForIndex(ft2, map_index); } - if(snap) - { - if(fabs(sw - 1) > 0.001 || fabs(sh - 1) > 0.001) - snap = false; // turn off pixel snapping for better animation - else - sw = sh = 1; - } dw = w * sw; dh = h * sh; @@ -1342,12 +1373,23 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma //ftbase_x = snap_to_pixel_x(ftbase_x); if(snap) + { + startx = snap_to_pixel_x(startx, 0.4); + starty = snap_to_pixel_y(starty, 0.4); ftbase_y = snap_to_pixel_y(ftbase_y, 0.3); + } pix_x = vid.width / vid_conwidth.value; pix_y = vid.height / vid_conheight.value; + + if (fontmap) + width_of = fontmap->width_of; + else + width_of = fnt->width_of; + for (shadow = r_textshadow.value != 0 && basealpha > 0;shadow >= 0;shadow--) { + prevch = 0; text = text_start; if (!outcolor || *outcolor == -1) @@ -1372,14 +1414,9 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma i = text - text_start; if (!ch) break; - if (snap) - { - x = snap_to_pixel_x(x, 0.4); - y = snap_to_pixel_y(y, 0.4); - } if (ch == ' ' && !fontmap) { - x += fnt->width_of[(int) ' '] * dw; + x += width_of[(int) ' '] * dw; continue; } if (ch == STRING_COLOR_TAG && !ignorecolorcodes && i < maxlen) @@ -1456,9 +1493,7 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma if (batchcount) { // switching from freetype to non-freetype rendering - GL_LockArrays(0, batchcount * 4); R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, quadelement3i, quadelement3s, 0, 0); - GL_LockArrays(0, 0); batchcount = 0; ac = color4f; at = texcoord2f; @@ -1495,25 +1530,21 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma batchcount++; if (batchcount >= QUADELEMENTS_MAXQUADS) { - GL_LockArrays(0, batchcount * 4); R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, quadelement3i, quadelement3s, 0, 0); - GL_LockArrays(0, 0); batchcount = 0; ac = color4f; at = texcoord2f; av = vertex3f; } - x += thisw * dw; + x += width_of[ch] * dw; } else { - if (!map || map == ft2_oldstyle_map || map->start < ch || map->start + FONT_CHARS_PER_MAP >= ch) + if (!map || map == ft2_oldstyle_map || ch < map->start || ch >= map->start + FONT_CHARS_PER_MAP) { // new charmap - need to render if (batchcount) { // we need a different character map, render what we currently have: - GL_LockArrays(0, batchcount * 4); R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, quadelement3i, quadelement3s, 0, 0); - GL_LockArrays(0, 0); batchcount = 0; ac = color4f; at = texcoord2f; @@ -1572,16 +1603,14 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma batchcount++; if (batchcount >= QUADELEMENTS_MAXQUADS) { - GL_LockArrays(0, batchcount * 4); R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, quadelement3i, quadelement3s, 0, 0); - GL_LockArrays(0, 0); batchcount = 0; ac = color4f; at = texcoord2f; av = vertex3f; } - prevmap = map; + //prevmap = map; prevch = ch; } if (shadow) @@ -1592,11 +1621,7 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma } } if (batchcount > 0) - { - GL_LockArrays(0, batchcount * 4); R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, quadelement3i, quadelement3s, 0, 0); - GL_LockArrays(0, 0); - } if (outcolor) *outcolor = colorindex; @@ -1713,9 +1738,7 @@ void DrawQ_Mesh (drawqueuemesh_t *mesh, int flags) R_Mesh_TexCoordPointer(0, 2, mesh->data_texcoord2f, 0, 0); R_SetupShader_Generic(mesh->texture, NULL, GL_MODULATE, 1); - GL_LockArrays(0, mesh->num_vertices); R_Mesh_Draw(0, mesh->num_vertices, 0, mesh->num_triangles, mesh->data_element3i, mesh->data_element3s, 0, 0); - GL_LockArrays(0, 0); } void DrawQ_LineLoop (drawqueuemesh_t *mesh, int flags)