X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=gl_draw.c;h=faa0c9180fa473a5c06bff3972f696c096a06831;hb=b93af3d74800726ac8703d04659e2adec9734671;hp=425c515911cc79452346a4cb8d3e8cfe4d4e9ff4;hpb=b5948d30a9cf9e2c851150307a338fe38f3dbd7b;p=xonotic%2Fdarkplaces.git diff --git a/gl_draw.c b/gl_draw.c index 425c5159..faa0c918 100644 --- a/gl_draw.c +++ b/gl_draw.c @@ -28,12 +28,21 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "ft2.h" #include "ft2_fontdefs.h" -dp_font_t dp_fonts[MAX_FONTS] = {{0}}; +dp_fonts_t dp_fonts; +static mempool_t *fonts_mempool = NULL; cvar_t r_textshadow = {CVAR_SAVE, "r_textshadow", "0", "draws a shadow on all text to improve readability (note: value controls offset, 1 = 1 pixel, 1.5 = 1.5 pixels, etc)"}; 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; //============================================================================= @@ -58,7 +67,7 @@ static rtexture_t *draw_generateconchars(void) double random; rtexture_t *tex; - data = LoadTGA_BGRA (concharimage, FONT_FILESIZE); + data = LoadTGA_BGRA (concharimage, FONT_FILESIZE, NULL); // Gold numbers for (i = 0;i < 8192;i++) { @@ -100,7 +109,7 @@ static rtexture_t *draw_generateconchars(void) Image_WriteTGABGRA ("gfx/generated_conchars.tga", 256, 256, data); #endif - tex = R_LoadTexture2D(drawtexturepool, "conchars", 256, 256, data, TEXTYPE_BGRA, TEXF_ALPHA, NULL); + tex = R_LoadTexture2D(drawtexturepool, "conchars", 256, 256, data, TEXTYPE_BGRA, TEXF_ALPHA, -1, NULL); Mem_Free(data); return tex; } @@ -112,7 +121,7 @@ static rtexture_t *draw_generateditherpattern(void) for (y = 0;y < 8;y++) for (x = 0;x < 8;x++) pixels[y][x] = ((x^y) & 4) ? 254 : 0; - return R_LoadTexture2D(drawtexturepool, "ditherpattern", 8, 8, pixels[0], TEXTYPE_PALETTE, TEXF_FORCENEAREST, palette_bgra_transparent); + return R_LoadTexture2D(drawtexturepool, "ditherpattern", 8, 8, pixels[0], TEXTYPE_PALETTE, TEXF_FORCENEAREST, -1, palette_bgra_transparent); } typedef struct embeddedpic_s @@ -283,7 +292,7 @@ static rtexture_t *draw_generatepic(const char *name, qboolean quiet) const embeddedpic_t *p; for (p = embeddedpics;p->name;p++) if (!strcmp(name, p->name)) - return R_LoadTexture2D(drawtexturepool, p->name, p->width, p->height, (const unsigned char *)p->pixels, TEXTYPE_PALETTE, TEXF_ALPHA, palette_bgra_embeddedpic); + return R_LoadTexture2D(drawtexturepool, p->name, p->width, p->height, (const unsigned char *)p->pixels, TEXTYPE_PALETTE, TEXF_ALPHA, -1, palette_bgra_embeddedpic); if (!strcmp(name, "gfx/conchars")) return draw_generateconchars(); if (!strcmp(name, "gfx/colorcontrol/ditherpattern")) @@ -347,15 +356,15 @@ 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, NULL); if (pixels == NULL && !strncmp(path, "gfx/", 4)) - pixels = loadimagepixelsbgra(path+4, false, true); + pixels = loadimagepixelsbgra(path+4, false, true, r_texture_convertsRGB_2d.integer, NULL); if (pixels) { pic->width = image_width; pic->height = image_height; if (!pic->autoload) - pic->tex = R_LoadTexture2D(drawtexturepool, path, image_width, image_height, pixels, TEXTYPE_BGRA, pic->texflags, NULL); + pic->tex = R_LoadTexture2D(drawtexturepool, path, image_width, image_height, pixels, TEXTYPE_BGRA, pic->texflags, -1, NULL); } else { @@ -380,7 +389,7 @@ cachepic_t *Draw_CachePic_Flags(const char *path, unsigned int cachepicflags) pic->height = lmpdata[4] + lmpdata[5] * 256 + lmpdata[6] * 65536 + lmpdata[7] * 16777216; // if no high quality replacement image was found, upload the original low quality texture if (!pixels) - pic->tex = R_LoadTexture2D(drawtexturepool, path, pic->width, pic->height, lmpdata + 8, TEXTYPE_PALETTE, pic->texflags, palette_bgra_transparent); + pic->tex = R_LoadTexture2D(drawtexturepool, path, pic->width, pic->height, lmpdata + 8, TEXTYPE_PALETTE, pic->texflags, -1, palette_bgra_transparent); } Mem_Free(lmpdata); } @@ -396,7 +405,7 @@ cachepic_t *Draw_CachePic_Flags(const char *path, unsigned int cachepicflags) pic->height = 128; // if no high quality replacement image was found, upload the original low quality texture if (!pixels) - pic->tex = R_LoadTexture2D(drawtexturepool, path, 128, 128, lmpdata, TEXTYPE_PALETTE, pic->texflags, palette_bgra_font); + pic->tex = R_LoadTexture2D(drawtexturepool, path, 128, 128, lmpdata, TEXTYPE_PALETTE, pic->texflags, -1, palette_bgra_font); } else { @@ -404,7 +413,7 @@ cachepic_t *Draw_CachePic_Flags(const char *path, unsigned int cachepicflags) pic->height = lmpdata[4] + lmpdata[5] * 256 + lmpdata[6] * 65536 + lmpdata[7] * 16777216; // if no high quality replacement image was found, upload the original low quality texture if (!pixels) - pic->tex = R_LoadTexture2D(drawtexturepool, path, pic->width, pic->height, lmpdata + 8, TEXTYPE_PALETTE, pic->texflags, palette_bgra_transparent); + pic->tex = R_LoadTexture2D(drawtexturepool, path, pic->width, pic->height, lmpdata + 8, TEXTYPE_PALETTE, pic->texflags, -1, palette_bgra_transparent); } } @@ -435,9 +444,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 +459,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) @@ -507,7 +514,7 @@ cachepic_t *Draw_NewPic(const char *picname, int width, int height, int alpha, u pic->height = height; if (pic->tex) R_FreeTexture(pic->tex); - pic->tex = R_LoadTexture2D(drawtexturepool, picname, width, height, pixels_bgra, TEXTYPE_BGRA, (alpha ? TEXF_ALPHA : 0) | TEXF_ALLOWUPDATES, NULL); + pic->tex = R_LoadTexture2D(drawtexturepool, picname, width, height, pixels_bgra, TEXTYPE_BGRA, (alpha ? TEXF_ALPHA : 0) | TEXF_ALLOWUPDATES, -1, NULL); return pic; } @@ -534,16 +541,31 @@ 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) +void LoadFont(qboolean override, const char *name, dp_font_t *fnt, float scale, float voffset) { int i; - float maxwidth, scale; + float maxwidth; char widthfile[MAX_QPATH]; char *widthbuf; fs_offset_t widthbufsize; if(override || !fnt->texpath[0]) + { strlcpy(fnt->texpath, name, sizeof(fnt->texpath)); + // load the cvars when the font is FIRST loader + fnt->settings.scale = scale; + fnt->settings.voffset = voffset; + 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; + } + // fix bad scale + if (fnt->settings.scale <= 0) + fnt->settings.scale = 1; if(drawtexturepool == NULL) return; // before gl_draw_start, so will be loaded later @@ -587,7 +609,6 @@ static void LoadFont(qboolean override, const char *name, dp_font_t *fnt) // unspecified width == 1 (base width) for(i = 1; i < 256; ++i) fnt->width_of[i] = 1; - scale = 1; // FIXME load "name.width", if it fails, fill all with 1 if((widthbuf = (char *) FS_LoadFile(widthfile, tempmempool, true, &widthbufsize))) @@ -619,8 +640,14 @@ static void LoadFont(qboolean override, const char *name, dp_font_t *fnt) fnt->width_of[ch] = atof(com_token) + extraspacing; if (fnt->ft2) { - for (i = 0; i < MAX_FONT_SIZES && fnt->req_sizes[i] >= 0; ++i) - Font_MapForIndex(fnt->ft2, i)->width_of[ch] = snap_to_pixel_x(fnt->width_of[ch] * fnt->req_sizes[i], 0.4); + 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; @@ -635,7 +662,7 @@ static void LoadFont(qboolean override, const char *name, dp_font_t *fnt) { if(!COM_ParseToken_Simple(&p, false, false)) return; - scale = atof(com_token); + fnt->settings.scale = atof(com_token); } else { @@ -656,19 +683,43 @@ static void LoadFont(qboolean override, const char *name, dp_font_t *fnt) fnt->maxwidth = maxwidth; // fix up maxwidth for overlap - fnt->maxwidth *= scale; - fnt->scale = scale; + fnt->maxwidth *= fnt->settings.scale; if(fnt == FONT_CONSOLE) con_linewidth = -1; // rewrap console in next frame } -static dp_font_t *FindFont(const char *title) +extern cvar_t developer_font; +dp_font_t *FindFont(const char *title, qboolean allocate_new) { int i; - for(i = 0; i < MAX_FONTS; ++i) - if(!strcmp(dp_fonts[i].title, title)) - return &dp_fonts[i]; + + // find font + for(i = 0; i < dp_fonts.maxsize; ++i) + if(!strcmp(dp_fonts.f[i].title, title)) + return &dp_fonts.f[i]; + // if not found - try allocate + if (allocate_new) + { + // find any font with empty title + for(i = 0; i < dp_fonts.maxsize; ++i) + { + if(!strcmp(dp_fonts.f[i].title, "")) + { + strlcpy(dp_fonts.f[i].title, title, sizeof(dp_fonts.f[i].title)); + return &dp_fonts.f[i]; + } + } + // if no any 'free' fonts - expand buffer + i = dp_fonts.maxsize; + dp_fonts.maxsize = dp_fonts.maxsize + FONTS_EXPAND; + if (developer_font.integer) + Con_Printf("FindFont: enlarging fonts buffer (%i -> %i)\n", i, dp_fonts.maxsize); + dp_fonts.f = Mem_Realloc(fonts_mempool, dp_fonts.f, sizeof(dp_font_t) * dp_fonts.maxsize); + // register a font in first expanded slot + strlcpy(dp_fonts.f[i].title, title, sizeof(dp_fonts.f[i].title)); + return &dp_fonts.f[i]; + } return NULL; } @@ -701,16 +752,17 @@ static float snap_to_pixel_y(float y, float roundUpAt) static void LoadFont_f(void) { dp_font_t *f; - int i; + int i, sizes; const char *filelist, *c, *cm; - float sz; + float sz, scale, voffset; char mainfont[MAX_QPATH]; if(Cmd_Argc() < 2) { Con_Printf("Available font commands:\n"); - for(i = 0; i < MAX_FONTS; ++i) - Con_Printf(" loadfont %s gfx/tgafile[...] [sizes...]\n", dp_fonts[i].title); + for(i = 0; i < dp_fonts.maxsize; ++i) + if (dp_fonts.f[i].title[0]) + Con_Printf(" loadfont %s gfx/tgafile[...] [custom switches] [sizes...]\n", dp_fonts.f[i].title); Con_Printf("A font can simply be gfx/tgafile, or alternatively you\n" "can specify multiple fonts and faces\n" "Like this: gfx/vera-sans:2,gfx/fallback:1\n" @@ -719,10 +771,13 @@ static void LoadFont_f(void) "You can also specify a list of font sizes to load, like this:\n" "loadfont console gfx/conchars,gfx/fallback 8 12 16 24 32\n" "In many cases, 8 12 16 24 32 should be a good choice.\n" + "custom switches:\n" + " scale x : scale all characters by this amount when rendering (doesnt change line height)\n" + " voffset x : offset all chars vertical when rendering, this is multiplied to character height\n" ); return; } - f = FindFont(Cmd_Argv(1)); + f = FindFont(Cmd_Argv(1), true); if(f == NULL) { Con_Printf("font function not found\n"); @@ -789,17 +844,38 @@ 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) + scale = 1; + voffset = 0; + if(Cmd_Argc() >= 4) { - for(i = 0; i < Cmd_Argc()-3; ++i) + for(sizes = 0, i = 3; i < Cmd_Argc(); ++i) { - sz = atof(Cmd_Argv(i+3)); + // special switches + if (!strcmp(Cmd_Argv(i), "scale")) + { + i++; + if (i < Cmd_Argc()) + scale = atof(Cmd_Argv(i)); + continue; + } + if (!strcmp(Cmd_Argv(i), "voffset")) + { + i++; + if (i < Cmd_Argc()) + voffset = atof(Cmd_Argv(i)); + continue; + } + // parse one of sizes + sz = atof(Cmd_Argv(i)); if (sz > 0.001f && sz < 1000.0f) // do not use crap sizes - f->req_sizes[i] = sz; + { + f->req_sizes[sizes] = sz; + sizes++; + } } } - LoadFont(true, mainfont, f); + + LoadFont(true, mainfont, f, scale, voffset); } /* @@ -817,8 +893,10 @@ static void gl_draw_start(void) font_start(); - for(i = 0; i < MAX_FONTS; ++i) - LoadFont(false, va("gfx/font_%s", dp_fonts[i].title), &dp_fonts[i]); + // load default font textures + for(i = 0; i < dp_fonts.maxsize; ++i) + if (dp_fonts.f[i].title[0]) + LoadFont(false, va("gfx/font_%s", dp_fonts.f[i].title), &dp_fonts.f[i], 1, 0); // draw the loading screen so people have something to see in the newly opened window SCR_UpdateLoadingScreen(true); @@ -842,14 +920,27 @@ 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); - Cmd_AddCommand ("loadfont",LoadFont_f, "loadfont function tganame loads a font; example: loadfont console gfx/veramono; loadfont without arguments lists the available functions"); - R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown, gl_draw_newmap); + // allocate fonts storage + fonts_mempool = Mem_AllocPool("FONTS", 0, NULL); + dp_fonts.maxsize = MAX_FONTS; + dp_fonts.f = Mem_Alloc(fonts_mempool, sizeof(dp_font_t) * dp_fonts.maxsize); + memset(dp_fonts.f, 0, sizeof(dp_font_t) * dp_fonts.maxsize); + + // assign starting font names strlcpy(FONT_DEFAULT->title, "default", sizeof(FONT_DEFAULT->title)); - strlcpy(FONT_DEFAULT->texpath, "gfx/conchars", sizeof(FONT_DEFAULT->texpath)); + strlcpy(FONT_DEFAULT->texpath, "gfx/conchars", sizeof(FONT_DEFAULT->texpath)); strlcpy(FONT_CONSOLE->title, "console", sizeof(FONT_CONSOLE->title)); strlcpy(FONT_SBAR->title, "sbar", sizeof(FONT_SBAR->title)); strlcpy(FONT_NOTIFY->title, "notify", sizeof(FONT_NOTIFY->title)); @@ -858,9 +949,11 @@ void GL_Draw_Init (void) strlcpy(FONT_INFOBAR->title, "infobar", sizeof(FONT_INFOBAR->title)); strlcpy(FONT_MENU->title, "menu", sizeof(FONT_MENU->title)); 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(); + if(!FONT_USER(i)->title[0]) + dpsnprintf(FONT_USER(i)->title, sizeof(FONT_USER(i)->title), "user%d", j++); + + Cmd_AddCommand ("loadfont",LoadFont_f, "loadfont function tganame loads a font; example: loadfont console gfx/veramono; loadfont without arguments lists the available functions"); + R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown, gl_draw_newmap); } void _DrawQ_Setup(void) @@ -905,14 +998,19 @@ static void _DrawQ_ProcessDrawFlag(int flags) void DrawQ_Pic(float x, float y, cachepic_t *pic, float width, float height, float red, float green, float blue, float alpha, int flags) { - float floats[20]; + float floats[36]; _DrawQ_ProcessDrawFlag(flags); - GL_Color(red, green, blue, alpha); - R_Mesh_VertexPointer(floats, 0, 0); - R_Mesh_ColorPointer(NULL, 0, 0); R_Mesh_ResetTextureState(); + floats[12] = 0.0f;floats[13] = 0.0f; + floats[14] = 1.0f;floats[15] = 0.0f; + floats[16] = 1.0f;floats[17] = 1.0f; + floats[18] = 0.0f;floats[19] = 1.0f; + floats[20] = floats[24] = floats[28] = floats[32] = red; + floats[21] = floats[25] = floats[29] = floats[33] = green; + floats[22] = floats[26] = floats[30] = floats[34] = blue; + floats[23] = floats[27] = floats[31] = floats[35] = alpha; if (pic) { if (width == 0) @@ -920,14 +1018,8 @@ void DrawQ_Pic(float x, float y, cachepic_t *pic, float width, float height, flo if (height == 0) height = pic->height; R_SetupShader_Generic(Draw_GetPicTexture(pic), NULL, GL_MODULATE, 1); - R_Mesh_TexCoordPointer(0, 2, floats + 12, 0, 0); - -#if 1 - floats[12] = 0.0f;floats[13] = 0.0f; - floats[14] = 1.0f;floats[15] = 0.0f; - floats[16] = 1.0f;floats[17] = 1.0f; - floats[18] = 0.0f;floats[19] = 1.0f; -#else + +#if 0 // AK07: lets be texel correct on the corners { float horz_offset = 0.5f / pic->width; @@ -949,12 +1041,13 @@ void DrawQ_Pic(float x, float y, cachepic_t *pic, float width, float height, flo floats[3] = floats[6] = x + width; floats[7] = floats[10] = y + height; - R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, polygonelement3s, 0, 0); + R_Mesh_PrepareVertices_Generic_Arrays(4, floats, floats + 20, floats + 12); + R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0); } void DrawQ_RotPic(float x, float y, cachepic_t *pic, float width, float height, float org_x, float org_y, float angle, float red, float green, float blue, float alpha, int flags) { - float floats[20]; + float floats[36]; float af = DEG2RAD(-angle); // forward float ar = DEG2RAD(-angle + 90); // right float sinaf = sin(af); @@ -963,10 +1056,7 @@ void DrawQ_RotPic(float x, float y, cachepic_t *pic, float width, float height, float cosar = cos(ar); _DrawQ_ProcessDrawFlag(flags); - GL_Color(red, green, blue, alpha); - R_Mesh_VertexPointer(floats, 0, 0); - R_Mesh_ColorPointer(NULL, 0, 0); R_Mesh_ResetTextureState(); if (pic) { @@ -975,12 +1065,6 @@ void DrawQ_RotPic(float x, float y, cachepic_t *pic, float width, float height, if (height == 0) height = pic->height; R_SetupShader_Generic(Draw_GetPicTexture(pic), NULL, GL_MODULATE, 1); - R_Mesh_TexCoordPointer(0, 2, floats + 12, 0, 0); - - floats[12] = 0.0f;floats[13] = 0.0f; - floats[14] = 1.0f;floats[15] = 0.0f; - floats[16] = 1.0f;floats[17] = 1.0f; - floats[18] = 0.0f;floats[19] = 1.0f; } else R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1); @@ -1003,18 +1087,25 @@ void DrawQ_RotPic(float x, float y, cachepic_t *pic, float width, float height, floats[9] = x - cosaf*org_x + cosar*(height-org_y); floats[10] = y - sinaf*org_x + sinar*(height-org_y); - R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, polygonelement3s, 0, 0); + floats[12] = 0.0f;floats[13] = 0.0f; + floats[14] = 1.0f;floats[15] = 0.0f; + floats[16] = 1.0f;floats[17] = 1.0f; + floats[18] = 0.0f;floats[19] = 1.0f; + floats[20] = floats[24] = floats[28] = floats[32] = red; + floats[21] = floats[25] = floats[29] = floats[33] = green; + floats[22] = floats[26] = floats[30] = floats[34] = blue; + floats[23] = floats[27] = floats[31] = floats[35] = alpha; + + R_Mesh_PrepareVertices_Generic_Arrays(4, floats, floats + 20, floats + 12); + R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0); } void DrawQ_Fill(float x, float y, float width, float height, float red, float green, float blue, float alpha, int flags) { - float floats[12]; + float floats[36]; _DrawQ_ProcessDrawFlag(flags); - GL_Color(red, green, blue, alpha); - R_Mesh_VertexPointer(floats, 0, 0); - R_Mesh_ColorPointer(NULL, 0, 0); R_Mesh_ResetTextureState(); R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1); @@ -1023,8 +1114,17 @@ void DrawQ_Fill(float x, float y, float width, float height, float red, float gr floats[1] = floats[4] = y; floats[3] = floats[6] = x + width; floats[7] = floats[10] = y + height; - - R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, polygonelement3s, 0, 0); + floats[12] = 0.0f;floats[13] = 0.0f; + floats[14] = 1.0f;floats[15] = 0.0f; + floats[16] = 1.0f;floats[17] = 1.0f; + floats[18] = 0.0f;floats[19] = 1.0f; + floats[20] = floats[24] = floats[28] = floats[32] = red; + floats[21] = floats[25] = floats[29] = floats[33] = green; + floats[22] = floats[26] = floats[30] = floats[34] = blue; + floats[23] = floats[27] = floats[31] = floats[35] = alpha; + + R_Mesh_PrepareVertices_Generic_Arrays(4, floats, floats + 20, floats + 12); + R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0); } /// color tag printing @@ -1093,13 +1193,13 @@ 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 width_of_factor; + float dw; // display w + //float dh; // display h const float *width_of; if (!h) h = w; @@ -1108,8 +1208,8 @@ float DrawQ_TextWidth_UntilWidth_TrackColors_Scale(const char *text, size_t *max snap = false; } // do this in the end - w *= fnt->scale; - h *= fnt->scale; + w *= fnt->settings.scale; + h *= fnt->settings.scale; // find the most fitting size: if (ft2 != NULL) @@ -1122,7 +1222,7 @@ float DrawQ_TextWidth_UntilWidth_TrackColors_Scale(const char *text, size_t *max } dw = w * sw; - dh = h * sh; + //dh = h * sh; if (*maxlen < 1) *maxlen = 1<<30; @@ -1145,15 +1245,9 @@ float DrawQ_TextWidth_UntilWidth_TrackColors_Scale(const char *text, size_t *max // x = snap_to_pixel_x(x, 0.4); // haha, it's 0 anyway if (fontmap) - { - width_of_factor = 1; width_of = fontmap->width_of; - } else - { - width_of_factor = dw; width_of = fnt->width_of; - } for (i = 0;((bytes_left = *maxlen - (text - text_start)) > 0) && *text;) { @@ -1165,12 +1259,12 @@ float DrawQ_TextWidth_UntilWidth_TrackColors_Scale(const char *text, size_t *max if (ch == ' ' && !fontmap) { if(!least_one || i0) // never skip the first character - if(x + width_of[(int) ' '] * width_of_factor > maxwidth) + if(x + width_of[(int) ' '] * dw > maxwidth) { i = i0; break; // oops, can't draw this } - x += width_of[(int) ' '] * width_of_factor; + x += width_of[(int) ' '] * dw; continue; } // i points to the char after ^ @@ -1237,14 +1331,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 + width_of[ch] * width_of_factor > maxwidth) + if(x + width_of[ch] * dw > maxwidth) { i = i0; break; // oops, can't draw this } - x += width_of[ch] * width_of_factor; + 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) @@ -1259,7 +1353,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; } } @@ -1287,7 +1381,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; @@ -1298,7 +1392,6 @@ 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; - float width_of_factor; const float *width_of; int tw, th; @@ -1311,9 +1404,9 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma snap = false; } - starty -= (fnt->scale - 1) * h * 0.5; // center - w *= fnt->scale; - h *= fnt->scale; + starty -= (fnt->settings.scale - 1) * h * 0.5 - fnt->settings.voffset*h; // center & offset + w *= fnt->settings.scale; + h *= fnt->settings.scale; if (ft2 != NULL) { @@ -1336,12 +1429,9 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma _DrawQ_ProcessDrawFlag(flags); - R_Mesh_ColorPointer(color4f, 0, 0); R_Mesh_ResetTextureState(); if (!fontmap) R_Mesh_TexBind(0, fnt->tex); - R_Mesh_TexCoordPointer(0, 2, texcoord2f, 0, 0); - R_Mesh_VertexPointer(vertex3f, 0, 0); R_SetupShader_Generic(fnt->tex, NULL, GL_MODULATE, 1); ac = color4f; @@ -1361,15 +1451,9 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma pix_y = vid.height / vid_conheight.value; if (fontmap) - { - width_of_factor = 1; width_of = fontmap->width_of; - } else - { - width_of_factor = dw; width_of = fnt->width_of; - } for (shadow = r_textshadow.value != 0 && basealpha > 0;shadow >= 0;shadow--) { @@ -1400,7 +1484,7 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma break; if (ch == ' ' && !fontmap) { - x += width_of[(int) ' '] * width_of_factor; + x += width_of[(int) ' '] * dw; continue; } if (ch == STRING_COLOR_TAG && !ignorecolorcodes && i < maxlen) @@ -1477,9 +1561,8 @@ 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); + R_Mesh_PrepareVertices_Generic_Arrays(batchcount * 4, vertex3f, color4f, texcoord2f); + R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, quadelement3i, NULL, 0, quadelement3s, NULL, 0); batchcount = 0; ac = color4f; at = texcoord2f; @@ -1516,25 +1599,23 @@ 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); + R_Mesh_PrepareVertices_Generic_Arrays(batchcount * 4, vertex3f, color4f, texcoord2f); + R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, quadelement3i, NULL, 0, quadelement3s, NULL, 0); batchcount = 0; ac = color4f; at = texcoord2f; av = vertex3f; } - x += width_of[ch] * width_of_factor; + 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); + R_Mesh_PrepareVertices_Generic_Arrays(batchcount * 4, vertex3f, color4f, texcoord2f); + R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, quadelement3i, NULL, 0, quadelement3s, NULL, 0); batchcount = 0; ac = color4f; at = texcoord2f; @@ -1593,16 +1674,15 @@ 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); + R_Mesh_PrepareVertices_Generic_Arrays(batchcount * 4, vertex3f, color4f, texcoord2f); + R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, quadelement3i, NULL, 0, quadelement3s, NULL, 0); batchcount = 0; ac = color4f; at = texcoord2f; av = vertex3f; } - prevmap = map; + //prevmap = map; prevch = ch; } if (shadow) @@ -1614,9 +1694,8 @@ 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); + R_Mesh_PrepareVertices_Generic_Arrays(batchcount * 4, vertex3f, color4f, texcoord2f); + R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, quadelement3i, NULL, 0, quadelement3s, NULL, 0); } if (outcolor) @@ -1692,8 +1771,6 @@ void DrawQ_SuperPic(float x, float y, cachepic_t *pic, float width, float height _DrawQ_ProcessDrawFlag(flags); - R_Mesh_VertexPointer(floats, 0, 0); - R_Mesh_ColorPointer(floats + 20, 0, 0); R_Mesh_ResetTextureState(); if (pic) { @@ -1702,11 +1779,6 @@ void DrawQ_SuperPic(float x, float y, cachepic_t *pic, float width, float height if (height == 0) height = pic->height; R_SetupShader_Generic(Draw_GetPicTexture(pic), NULL, GL_MODULATE, 1); - R_Mesh_TexCoordPointer(0, 2, floats + 12, 0, 0); - floats[12] = s1;floats[13] = t1; - floats[14] = s2;floats[15] = t2; - floats[16] = s4;floats[17] = t4; - floats[18] = s3;floats[19] = t3; } else R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1); @@ -1716,27 +1788,28 @@ void DrawQ_SuperPic(float x, float y, cachepic_t *pic, float width, float height floats[1] = floats[4] = y; floats[3] = floats[6] = x + width; floats[7] = floats[10] = y + height; + floats[12] = s1;floats[13] = t1; + floats[14] = s2;floats[15] = t2; + floats[16] = s4;floats[17] = t4; + floats[18] = s3;floats[19] = t3; floats[20] = r1;floats[21] = g1;floats[22] = b1;floats[23] = a1; floats[24] = r2;floats[25] = g2;floats[26] = b2;floats[27] = a2; floats[28] = r4;floats[29] = g4;floats[30] = b4;floats[31] = a4; floats[32] = r3;floats[33] = g3;floats[34] = b3;floats[35] = a3; - R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, polygonelement3s, 0, 0); + R_Mesh_PrepareVertices_Generic_Arrays(4, floats, floats + 20, floats + 12); + R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0); } void DrawQ_Mesh (drawqueuemesh_t *mesh, int flags) { _DrawQ_ProcessDrawFlag(flags); - R_Mesh_VertexPointer(mesh->data_vertex3f, 0, 0); - R_Mesh_ColorPointer(mesh->data_color4f, 0, 0); R_Mesh_ResetTextureState(); - 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); + R_Mesh_PrepareVertices_Generic_Arrays(mesh->num_vertices, mesh->data_vertex3f, mesh->data_color4f, mesh->data_texcoord2f); + R_Mesh_Draw(0, mesh->num_vertices, 0, mesh->num_triangles, mesh->data_element3i, NULL, 0, mesh->data_element3s, NULL, 0); } void DrawQ_LineLoop (drawqueuemesh_t *mesh, int flags) @@ -1822,8 +1895,6 @@ void R_DrawGamma(void) break; } // all the blends ignore depth - R_Mesh_VertexPointer(blendvertex3f, 0, 0); - R_Mesh_ColorPointer(NULL, 0, 0); R_Mesh_ResetTextureState(); R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1); GL_DepthMask(true); @@ -1843,8 +1914,9 @@ void R_DrawGamma(void) GL_BlendFunc(GL_DST_COLOR, GL_ONE); while (c[0] >= 1.01f || c[1] >= 1.01f || c[2] >= 1.01f) { - GL_Color(bound(0, c[0] - 1, 1), bound(0, c[1] - 1, 1), bound(0, c[2] - 1, 1), 1); - R_Mesh_Draw(0, 3, 0, 1, polygonelement3i, polygonelement3s, 0, 0); + GL_Color(c[0] - 1, c[1] - 1, c[2] - 1, 1); + R_Mesh_PrepareVertices_Generic_Arrays(3, blendvertex3f, NULL, NULL); + R_Mesh_Draw(0, 3, 0, 1, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0); VectorScale(c, 0.5, c); } } @@ -1859,8 +1931,9 @@ void R_DrawGamma(void) if (c[0] >= 0.01f || c[1] >= 0.01f || c[2] >= 0.01f) { GL_BlendFunc(GL_ONE, GL_ONE); - GL_Color(c[0], c[1], c[2], 1); - R_Mesh_Draw(0, 3, 0, 1, polygonelement3i, polygonelement3s, 0, 0); + GL_Color(c[0] - 1, c[1] - 1, c[2] - 1, 1); + R_Mesh_PrepareVertices_Generic_Arrays(3, blendvertex3f, NULL, NULL); + R_Mesh_Draw(0, 3, 0, 1, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0); } }