]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_draw.c
changed DP_SMALLMEMORY compiles to use the standard NET_MAXMESSAGE value
[xonotic/darkplaces.git] / gl_draw.c
index 7a4cad352402321e3081aaa81bddc038607901e1..2675d414a755d42941a740867e93c38e112c4b6d 100644 (file)
--- 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;
 
 //=============================================================================
@@ -532,6 +540,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 +551,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 +635,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 +814,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 +823,7 @@ static void LoadFont_f(void)
                                f->req_sizes[i] = sz;
                }
        }
+
        LoadFont(true, mainfont, f);
 }
 
@@ -835,6 +867,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 +892,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)
@@ -1072,7 +1110,7 @@ static void DrawQ_GetTextColor(float color[4], int colorindex, float r, float g,
 }
 
 // NOTE: this function always draws exactly one character if maxwidth <= 0
-float DrawQ_TextWidth_Font_UntilWidth_TrackColors_Size_Scale(const char *text, size_t *maxlen, float w, float h, float sw, float sh, int *outcolor, qboolean ignorecolorcodes, const dp_font_t *fnt, float maxwidth)
+float DrawQ_TextWidth_UntilWidth_TrackColors_Scale(const char *text, size_t *maxlen, float w, float h, float sw, float sh, int *outcolor, qboolean ignorecolorcodes, const dp_font_t *fnt, float maxwidth)
 {
        const char *text_start = text;
        int colorindex = STRING_COLOR_DEFAULT;
@@ -1092,6 +1130,7 @@ float DrawQ_TextWidth_Font_UntilWidth_TrackColors_Size_Scale(const char *text, s
        qboolean snap = true;
        qboolean least_one = false;
        float dw, dh; // display w/h
+       const float *width_of;
 
        if (!h) h = w;
        if (!h) {
@@ -1111,13 +1150,6 @@ float DrawQ_TextWidth_Font_UntilWidth_TrackColors_Size_Scale(const char *text, s
                        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;
@@ -1139,6 +1171,14 @@ float DrawQ_TextWidth_Font_UntilWidth_TrackColors_Size_Scale(const char *text, s
                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 +1186,15 @@ float DrawQ_TextWidth_Font_UntilWidth_TrackColors_Size_Scale(const char *text, s
                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 +1261,14 @@ float DrawQ_TextWidth_Font_UntilWidth_TrackColors_Size_Scale(const char *text, s
                                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)
@@ -1258,7 +1296,7 @@ float DrawQ_TextWidth_Font_UntilWidth_TrackColors_Size_Scale(const char *text, s
        return x;
 }
 
-float DrawQ_String_Font_Scale(float startx, float starty, const char *text, size_t maxlen, float w, float h, float sw, float sh, float basered, float basegreen, float baseblue, float basealpha, int flags, int *outcolor, qboolean ignorecolorcodes, const dp_font_t *fnt)
+float DrawQ_String_Scale(float startx, float starty, const char *text, size_t maxlen, float w, float h, float sw, float sh, float basered, float basegreen, float baseblue, float basealpha, int flags, int *outcolor, qboolean ignorecolorcodes, const dp_font_t *fnt)
 {
        int shadow, colorindex = STRING_COLOR_DEFAULT;
        size_t i;
@@ -1284,6 +1322,7 @@ float DrawQ_String_Font_Scale(float startx, float starty, const char *text, size
        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 +1346,6 @@ float DrawQ_String_Font_Scale(float startx, float starty, const char *text, size
                        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 +1374,23 @@ float DrawQ_String_Font_Scale(float startx, float starty, const char *text, size
 
        //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 +1415,9 @@ float DrawQ_String_Font_Scale(float startx, float starty, const char *text, size
                        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 +1494,7 @@ float DrawQ_String_Font_Scale(float startx, float starty, const char *text, size
                                                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 +1531,21 @@ float DrawQ_String_Font_Scale(float startx, float starty, const char *text, size
                                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,9 +1604,7 @@ float DrawQ_String_Font_Scale(float startx, float starty, const char *text, size
                                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;
@@ -1592,11 +1622,7 @@ float DrawQ_String_Font_Scale(float startx, float starty, const char *text, size
                }
        }
        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;
@@ -1605,29 +1631,24 @@ float DrawQ_String_Font_Scale(float startx, float starty, const char *text, size
        return x;
 }
 
-float DrawQ_String_Font(float startx, float starty, const char *text, size_t maxlen, float w, float h, float basered, float basegreen, float baseblue, float basealpha, int flags, int *outcolor, qboolean ignorecolorcodes, const dp_font_t *fnt)
-{
-       return DrawQ_String_Font_Scale(startx, starty, text, maxlen, w, h, 1, 1, basered, basegreen, baseblue, basealpha, flags, outcolor, ignorecolorcodes, fnt);
-}
-
-float DrawQ_String(float startx, float starty, const char *text, size_t maxlen, float w, float h, float basered, float basegreen, float baseblue, float basealpha, int flags, int *outcolor, qboolean ignorecolorcodes)
+float DrawQ_String(float startx, float starty, const char *text, size_t maxlen, float w, float h, float basered, float basegreen, float baseblue, float basealpha, int flags, int *outcolor, qboolean ignorecolorcodes, const dp_font_t *fnt)
 {
-       return DrawQ_String_Font(startx, starty, text, maxlen, w, h, basered, basegreen, baseblue, basealpha, flags, outcolor, ignorecolorcodes, &dp_fonts[0]);
+       return DrawQ_String_Scale(startx, starty, text, maxlen, w, h, 1, 1, basered, basegreen, baseblue, basealpha, flags, outcolor, ignorecolorcodes, fnt);
 }
 
-float DrawQ_TextWidth_Font_UntilWidth_TrackColors_Size(const char *text, size_t *maxlen, float w, float h, int *outcolor, qboolean ignorecolorcodes, const dp_font_t *fnt, float maxwidth)
+float DrawQ_TextWidth_UntilWidth_TrackColors(const char *text, size_t *maxlen, float w, float h, int *outcolor, qboolean ignorecolorcodes, const dp_font_t *fnt, float maxwidth)
 {
-       return DrawQ_TextWidth_Font_UntilWidth_TrackColors_Size_Scale(text, maxlen, w, h, 1, 1, outcolor, ignorecolorcodes, fnt, maxwidth);
+       return DrawQ_TextWidth_UntilWidth_TrackColors_Scale(text, maxlen, w, h, 1, 1, outcolor, ignorecolorcodes, fnt, maxwidth);
 }
 
-float DrawQ_TextWidth_Font(const char *text, size_t maxlen, float w, float h, qboolean ignorecolorcodes, const dp_font_t *fnt)
+float DrawQ_TextWidth(const char *text, size_t maxlen, float w, float h, qboolean ignorecolorcodes, const dp_font_t *fnt)
 {
-       return DrawQ_TextWidth_Font_UntilWidth_Size(text, &maxlen, w, h, ignorecolorcodes, fnt, 1000000000);
+       return DrawQ_TextWidth_UntilWidth(text, &maxlen, w, h, ignorecolorcodes, fnt, 1000000000);
 }
 
-float DrawQ_TextWidth_Font_UntilWidth_Size(const char *text, size_t *maxlen, float w, float h, qboolean ignorecolorcodes, const dp_font_t *fnt, float maxWidth)
+float DrawQ_TextWidth_UntilWidth(const char *text, size_t *maxlen, float w, float h, qboolean ignorecolorcodes, const dp_font_t *fnt, float maxWidth)
 {
-       return DrawQ_TextWidth_Font_UntilWidth_TrackColors_Size(text, maxlen, w, h, NULL, ignorecolorcodes, fnt, maxWidth);
+       return DrawQ_TextWidth_UntilWidth_TrackColors(text, maxlen, w, h, NULL, ignorecolorcodes, fnt, maxWidth);
 }
 
 #if 0
@@ -1718,9 +1739,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)