X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=gl_draw.c;h=686ffb5b9724e0d0cca3b3fbe95d0f16ad6a540b;hp=47a90f9c48b1115dfad4f04e670e44d9fa57bd18;hb=8637b1ec26ca72f92d1ef8faf23a2f124c1f4ff3;hpb=35b7d263c31d6576b488a3df4c1b06ad5acb3ecd diff --git a/gl_draw.c b/gl_draw.c index 47a90f9c..686ffb5b 100644 --- a/gl_draw.c +++ b/gl_draw.c @@ -50,19 +50,19 @@ struct cachepic_s 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" */}; -cvar_t r_nearest_2d = {CVAR_SAVE, "r_nearest_2d", "0", "use nearest filtering on all 2d textures (including conchars)"}; -cvar_t r_nearest_conchars = {CVAR_SAVE, "r_nearest_conchars", "0", "use nearest filtering on conchars texture"}; +cvar_t r_textshadow = {CVAR_CLIENT | 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_CLIENT | 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_CLIENT | 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_CLIENT | CVAR_SAVE, "r_font_postprocess_blur", "0", "font blur amount"}; +cvar_t r_font_postprocess_outline = {CVAR_CLIENT | CVAR_SAVE, "r_font_postprocess_outline", "0", "font outline amount"}; +cvar_t r_font_postprocess_shadow_x = {CVAR_CLIENT | CVAR_SAVE, "r_font_postprocess_shadow_x", "0", "font shadow X shift amount, applied during outlining"}; +cvar_t r_font_postprocess_shadow_y = {CVAR_CLIENT | CVAR_SAVE, "r_font_postprocess_shadow_y", "0", "font shadow Y shift amount, applied during outlining"}; +cvar_t r_font_postprocess_shadow_z = {CVAR_CLIENT | CVAR_SAVE, "r_font_postprocess_shadow_z", "0", "font shadow Z shift amount, applied during blurring"}; +cvar_t r_font_hinting = {CVAR_CLIENT | CVAR_SAVE, "r_font_hinting", "3", "0 = no hinting, 1 = light autohinting, 2 = full autohinting, 3 = full hinting"}; +cvar_t r_font_antialias = {CVAR_CLIENT | CVAR_SAVE, "r_font_antialias", "1", "0 = monochrome, 1 = grey" /* , 2 = rgb, 3 = bgr" */}; +cvar_t r_nearest_2d = {CVAR_CLIENT | CVAR_SAVE, "r_nearest_2d", "0", "use nearest filtering on all 2d textures (including conchars)"}; +cvar_t r_nearest_conchars = {CVAR_CLIENT | CVAR_SAVE, "r_nearest_conchars", "0", "use nearest filtering on conchars texture"}; //============================================================================= /* Support Routines */ @@ -105,32 +105,39 @@ cachepic_t *Draw_CachePic_Flags(const char *path, unsigned int cachepicflags) if (!strcmp(path, pic->name)) { // if it was created (or replaced) by Draw_NewPic, just return it - if (pic->flags & CACHEPICFLAG_NEWPIC) - { - if (pic->skinframe) - R_SkinFrame_MarkUsed(pic->skinframe); - pic->lastusedframe = draw_frame; - return pic; - } - if (!((pic->texflags ^ texflags) & ~(TEXF_COMPRESS | TEXF_MIPMAP))) // ignore TEXF_COMPRESS when comparing, because fallback pics remove the flag, and ignore TEXF_MIPMAP because QC specifies that + if (!(pic->flags & CACHEPICFLAG_NEWPIC)) { + // reload the pic if texflags changed in important ways + // ignore TEXF_COMPRESS when comparing, because fallback pics remove the flag, and ignore TEXF_MIPMAP because QC specifies that + if ((pic->texflags ^ texflags) & ~(TEXF_COMPRESS | TEXF_MIPMAP)) + { + Con_DPrintf("Draw_CachePic(\"%s\"): frame %i: reloading pic due to mismatch on flags\n", path, draw_frame); + goto reload; + } if (!pic->skinframe || !pic->skinframe->base) + { + if (pic->flags & CACHEPICFLAG_FAILONMISSING) + return NULL; + Con_DPrintf("Draw_CachePic(\"%s\"): frame %i: reloading pic\n", path, draw_frame); goto reload; + } if (!(cachepicflags & CACHEPICFLAG_NOTPERSISTENT)) pic->autoload = false; // caller is making this pic persistent - R_SkinFrame_MarkUsed(pic->skinframe); - pic->lastusedframe = draw_frame; - return pic; } + if (pic->skinframe) + R_SkinFrame_MarkUsed(pic->skinframe); + pic->lastusedframe = draw_frame; + return pic; } } if (numcachepics == MAX_CACHED_PICS) { - Con_Printf ("Draw_CachePic: numcachepics == MAX_CACHED_PICS\n"); + Con_DPrintf ("Draw_CachePic(\"%s\"): frame %i: numcachepics == MAX_CACHED_PICS\n", path, draw_frame); // FIXME: support NULL in callers? return cachepics; // return the first one } + Con_DPrintf("Draw_CachePic(\"%s\"): frame %i: loading pic%s\n", path, draw_frame, (cachepicflags & CACHEPICFLAG_NOTPERSISTENT) ? " notpersist" : ""); pic = cachepics + (numcachepics++); memset(pic, 0, sizeof(*pic)); strlcpy (pic->name, path, sizeof(pic->name)); @@ -147,8 +154,16 @@ reload: pic->autoload = (cachepicflags & CACHEPICFLAG_NOTPERSISTENT) != 0; pic->lastusedframe = draw_frame; - // load high quality image (this falls back to low quality too) - pic->skinframe = R_SkinFrame_LoadExternal(pic->name, texflags | TEXF_FORCE_RELOAD, (cachepicflags & CACHEPICFLAG_QUIET) == 0, (cachepicflags & CACHEPICFLAG_FAILONMISSING) == 0); + if (pic->skinframe) + { + // reload image after it was unloaded or texflags changed significantly + R_SkinFrame_LoadExternal_SkinFrame(pic->skinframe, pic->name, texflags | TEXF_FORCE_RELOAD, (cachepicflags & CACHEPICFLAG_QUIET) == 0, (cachepicflags & CACHEPICFLAG_FAILONMISSING) == 0); + } + else + { + // load high quality image (this falls back to low quality too) + pic->skinframe = R_SkinFrame_LoadExternal(pic->name, texflags | TEXF_FORCE_RELOAD, (cachepicflags & CACHEPICFLAG_QUIET) == 0, (cachepicflags & CACHEPICFLAG_FAILONMISSING) == 0); + } // get the dimensions of the image we loaded (if it was successful) if (pic->skinframe && pic->skinframe->base) @@ -194,7 +209,10 @@ qboolean Draw_IsPicLoaded(cachepic_t *pic) if (pic == NULL) return false; if (pic->autoload && (!pic->skinframe || !pic->skinframe->base)) + { + Con_DPrintf("Draw_IsPicLoaded(\"%s\"): Loading external skin\n", pic->name); pic->skinframe = R_SkinFrame_LoadExternal(pic->name, pic->texflags | TEXF_FORCE_RELOAD, false, true); + } // skinframe will only be NULL if the pic was created with CACHEPICFLAG_FAILONMISSING and not found return pic->skinframe != NULL && pic->skinframe->base != NULL; } @@ -204,7 +222,10 @@ rtexture_t *Draw_GetPicTexture(cachepic_t *pic) if (pic == NULL) return NULL; if (pic->autoload && (!pic->skinframe || !pic->skinframe->base)) + { + Con_DPrintf("Draw_GetPicTexture(\"%s\"): Loading external skin\n", pic->name); pic->skinframe = R_SkinFrame_LoadExternal(pic->name, pic->texflags | TEXF_FORCE_RELOAD, false, true); + } pic->lastusedframe = draw_frame; return pic->skinframe ? pic->skinframe->base : NULL; } @@ -218,8 +239,13 @@ void Draw_Frame(void) return; nextpurgetime = realtime + 0.05; for (i = 0, pic = cachepics;i < numcachepics;i++, pic++) - if (pic->autoload && pic->skinframe && pic->skinframe->base && pic->lastusedframe < draw_frame) + { + if (pic->autoload && pic->skinframe && pic->skinframe->base && pic->lastusedframe < draw_frame - 3) + { + Con_DPrintf("Draw_Frame(%i): Unloading \"%s\"\n", draw_frame, pic->name); R_SkinFrame_PurgeSkinFrame(pic->skinframe); + } + } draw_frame++; } @@ -238,20 +264,23 @@ cachepic_t *Draw_NewPic(const char *picname, int width, int height, unsigned cha { if (pic->flags & CACHEPICFLAG_NEWPIC && pic->skinframe && pic->skinframe->base && pic->width == width && pic->height == height) { + Con_DPrintf("Draw_NewPic(\"%s\"): frame %i: updating texture\n", picname, draw_frame); R_UpdateTexture(pic->skinframe->base, pixels_bgra, 0, 0, 0, width, height, 1); R_SkinFrame_MarkUsed(pic->skinframe); pic->lastusedframe = draw_frame; return pic; } + Con_DPrintf("Draw_NewPic(\"%s\"): frame %i: reloading pic because flags/size changed\n", picname, draw_frame); } else { if (numcachepics == MAX_CACHED_PICS) { - Con_Printf ("Draw_NewPic: numcachepics == MAX_CACHED_PICS\n"); + Con_DPrintf ("Draw_NewPic(\"%s\"): frame %i: numcachepics == MAX_CACHED_PICS\n", picname, draw_frame); // FIXME: support NULL in callers? return cachepics; // return the first one } + Con_DPrintf("Draw_NewPic(\"%s\"): frame %i: creating new cachepic\n", picname, draw_frame); pic = cachepics + (numcachepics++); memset(pic, 0, sizeof(*pic)); strlcpy (pic->name, picname, sizeof(pic->name)); @@ -262,12 +291,13 @@ cachepic_t *Draw_NewPic(const char *picname, int width, int height, unsigned cha R_SkinFrame_PurgeSkinFrame(pic->skinframe); + pic->autoload = false; pic->flags = CACHEPICFLAG_NEWPIC; // disable texflags checks in Draw_CachePic pic->flags |= (texflags & TEXF_CLAMP) ? 0 : CACHEPICFLAG_NOCLAMP; pic->flags |= (texflags & TEXF_FORCENEAREST) ? CACHEPICFLAG_NEAREST : 0; pic->width = width; pic->height = height; - pic->skinframe = R_SkinFrame_LoadInternalBGRA(picname, texflags | TEXF_FORCE_RELOAD, pixels_bgra, width, height, vid.sRGB2D); + pic->skinframe = R_SkinFrame_LoadInternalBGRA(picname, texflags | TEXF_FORCE_RELOAD, pixels_bgra, width, height, 0, 0, 0, vid.sRGB2D); pic->lastusedframe = draw_frame; return pic; } @@ -284,9 +314,8 @@ void Draw_FreePic(const char *picname) { if (!strcmp (picname, pic->name) && pic->skinframe) { + Con_DPrintf("Draw_FreePic(\"%s\"): frame %i: freeing pic\n", picname, draw_frame); R_SkinFrame_PurgeSkinFrame(pic->skinframe); - pic->width = 0; - pic->height = 0; return; } } @@ -408,7 +437,7 @@ void LoadFont(qboolean override, const char *name, dp_font_t *fnt, float scale, } else { - Con_Printf("Warning: skipped unknown font property %s\n", com_token); + Con_DPrintf("Warning: skipped unknown font property %s\n", com_token); if(!COM_ParseToken_Simple(&p, false, false, true)) return; } @@ -507,7 +536,7 @@ static float snap_to_pixel_y(float y, float roundUpAt) */ } -static void LoadFont_f(void) +static void LoadFont_f(cmd_state_t *cmd) { dp_font_t *f; int i, sizes; @@ -515,7 +544,7 @@ static void LoadFont_f(void) float sz, scale, voffset; char mainfont[MAX_QPATH]; - if(Cmd_Argc() < 2) + if(Cmd_Argc(cmd) < 2) { Con_Printf("Available font commands:\n"); for(i = 0; i < dp_fonts.maxsize; ++i) @@ -535,17 +564,17 @@ static void LoadFont_f(void) ); return; } - f = FindFont(Cmd_Argv(1), true); + f = FindFont(Cmd_Argv(cmd, 1), true); if(f == NULL) { Con_Printf("font function not found\n"); return; } - if(Cmd_Argc() < 3) + if(Cmd_Argc(cmd) < 3) filelist = "gfx/conchars"; else - filelist = Cmd_Argv(2); + filelist = Cmd_Argv(cmd, 2); memset(f->fallbacks, 0, sizeof(f->fallbacks)); memset(f->fallback_faces, 0, sizeof(f->fallback_faces)); @@ -604,23 +633,23 @@ static void LoadFont_f(void) scale = 1; voffset = 0; - if(Cmd_Argc() >= 4) + if(Cmd_Argc(cmd) >= 4) { - for(sizes = 0, i = 3; i < Cmd_Argc(); ++i) + for(sizes = 0, i = 3; i < Cmd_Argc(cmd); ++i) { // special switches - if (!strcmp(Cmd_Argv(i), "scale")) + if (!strcmp(Cmd_Argv(cmd, i), "scale")) { i++; - if (i < Cmd_Argc()) - scale = atof(Cmd_Argv(i)); + if (i < Cmd_Argc(cmd)) + scale = atof(Cmd_Argv(cmd, i)); continue; } - if (!strcmp(Cmd_Argv(i), "voffset")) + if (!strcmp(Cmd_Argv(cmd, i), "voffset")) { i++; - if (i < Cmd_Argc()) - voffset = atof(Cmd_Argv(i)); + if (i < Cmd_Argc(cmd)) + voffset = atof(Cmd_Argv(cmd, i)); continue; } @@ -628,7 +657,7 @@ static void LoadFont_f(void) continue; // no slot for other sizes // parse one of sizes - sz = atof(Cmd_Argv(i)); + sz = atof(Cmd_Argv(cmd, i)); if (sz > 0.001f && sz < 1000.0f) // do not use crap sizes { // search for duplicated sizes @@ -641,7 +670,7 @@ static void LoadFont_f(void) if (sizes == MAX_FONT_SIZES) { - Con_Printf("Warning: specified more than %i different font sizes, exceding ones are ignored\n", MAX_FONT_SIZES); + Con_Warnf("Warning: specified more than %i different font sizes, exceding ones are ignored\n", MAX_FONT_SIZES); sizes = -1; continue; } @@ -674,9 +703,6 @@ static void gl_draw_start(void) for(i = 0; i < dp_fonts.maxsize; ++i) if (dp_fonts.f[i].title[0]) LoadFont(false, va(vabuf, sizeof(vabuf), "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, true); } static void gl_draw_shutdown(void) @@ -740,7 +766,7 @@ void GL_Draw_Init (void) 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"); + Cmd_AddCommand(CMD_CLIENT, "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, NULL, NULL); } @@ -759,11 +785,13 @@ void DrawQ_Pic(float x, float y, cachepic_t *pic, float width, float height, flo int e0, e1, e2, e3; if (!pic) pic = Draw_CachePic("white"); + // make sure pic is loaded - we don't use the texture here, Mod_Mesh_GetTexture looks up the skinframe by name + Draw_GetPicTexture(pic); if (width == 0) width = pic->width; if (height == 0) height = pic->height; - surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, pic->name, flags, pic->texflags, MATERIALFLAG_VERTEXCOLOR), true); + surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, pic->name, flags, pic->texflags, MATERIALFLAG_WALL | MATERIALFLAG_VERTEXCOLOR | MATERIALFLAG_ALPHAGEN_VERTEX | MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW), true); e0 = Mod_Mesh_IndexForVertex(mod, surf, x , y , 0, 0, 0, -1, 0, 0, 0, 0, red, green, blue, alpha); e1 = Mod_Mesh_IndexForVertex(mod, surf, x + width, y , 0, 0, 0, -1, 1, 0, 0, 0, red, green, blue, alpha); e2 = Mod_Mesh_IndexForVertex(mod, surf, x + width, y + height, 0, 0, 0, -1, 1, 1, 0, 0, red, green, blue, alpha); @@ -785,11 +813,13 @@ void DrawQ_RotPic(float x, float y, cachepic_t *pic, float width, float height, int e0, e1, e2, e3; if (!pic) pic = Draw_CachePic("white"); + // make sure pic is loaded - we don't use the texture here, Mod_Mesh_GetTexture looks up the skinframe by name + Draw_GetPicTexture(pic); if (width == 0) width = pic->width; if (height == 0) height = pic->height; - surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, pic->name, flags, pic->texflags, MATERIALFLAG_VERTEXCOLOR), true); + surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, pic->name, flags, pic->texflags, MATERIALFLAG_WALL | MATERIALFLAG_VERTEXCOLOR | MATERIALFLAG_ALPHAGEN_VERTEX | MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW), true); e0 = Mod_Mesh_IndexForVertex(mod, surf, x - cosaf * org_x - cosar * org_y , y - sinaf * org_x - sinar * org_y , 0, 0, 0, -1, 0, 0, 0, 0, red, green, blue, alpha); e1 = Mod_Mesh_IndexForVertex(mod, surf, x + cosaf * (width - org_x) - cosar * org_y , y + sinaf * (width - org_x) - sinar * org_y , 0, 0, 0, -1, 1, 0, 0, 0, red, green, blue, alpha); e2 = Mod_Mesh_IndexForVertex(mod, surf, x + cosaf * (width - org_x) + cosar * (height - org_y), y + sinaf * (width - org_x) + sinar * (height - org_y), 0, 0, 0, -1, 1, 1, 0, 0, red, green, blue, alpha); @@ -807,8 +837,8 @@ void DrawQ_Fill(float x, float y, float width, float height, float red, float gr static const vec4_t string_colors[] = { // Quake3 colors - // LordHavoc: why on earth is cyan before magenta in Quake3? - // LordHavoc: note: Doom3 uses white for [0] and [7] + // LadyHavoc: why on earth is cyan before magenta in Quake3? + // LadyHavoc: note: Doom3 uses white for [0] and [7] {0.0, 0.0, 0.0, 1.0}, // black {1.0, 0.0, 0.0, 1.0}, // red {0.0, 1.0, 0.0, 1.0}, // green @@ -1240,7 +1270,7 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma u = 0.0625f * thisw - (1.0f / tw); v = 0.0625f - (1.0f / th); } - surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, fnt->pic->name, flags, TEXF_ALPHA | TEXF_CLAMP, MATERIALFLAG_VERTEXCOLOR), true); + surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, fnt->pic->name, flags, TEXF_ALPHA | TEXF_CLAMP, MATERIALFLAG_WALL | MATERIALFLAG_VERTEXCOLOR | MATERIALFLAG_ALPHAGEN_VERTEX | MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW), true); e0 = Mod_Mesh_IndexForVertex(mod, surf, x , y , 10, 0, 0, -1, s , t , 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]); e1 = Mod_Mesh_IndexForVertex(mod, surf, x+dw*thisw, y , 10, 0, 0, -1, s+u, t , 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]); e2 = Mod_Mesh_IndexForVertex(mod, surf, x+dw*thisw, y+dh, 10, 0, 0, -1, s+u, t+v, 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]); @@ -1281,7 +1311,7 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma } else kx = ky = 0; - surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, map->pic->name, flags, TEXF_ALPHA | TEXF_CLAMP, MATERIALFLAG_VERTEXCOLOR), true); + surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, map->pic->name, flags, TEXF_ALPHA | TEXF_CLAMP, MATERIALFLAG_WALL | MATERIALFLAG_VERTEXCOLOR | MATERIALFLAG_ALPHAGEN_VERTEX | MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW), true); e0 = Mod_Mesh_IndexForVertex(mod, surf, x + dw * map->glyphs[mapch].vxmin, y + dh * map->glyphs[mapch].vymin, 10, 0, 0, -1, map->glyphs[mapch].txmin, map->glyphs[mapch].tymin, 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]); e1 = Mod_Mesh_IndexForVertex(mod, surf, x + dw * map->glyphs[mapch].vxmax, y + dh * map->glyphs[mapch].vymin, 10, 0, 0, -1, map->glyphs[mapch].txmax, map->glyphs[mapch].tymin, 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]); e2 = Mod_Mesh_IndexForVertex(mod, surf, x + dw * map->glyphs[mapch].vxmax, y + dh * map->glyphs[mapch].vymax, 10, 0, 0, -1, map->glyphs[mapch].txmax, map->glyphs[mapch].tymax, 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]); @@ -1379,11 +1409,13 @@ void DrawQ_SuperPic(float x, float y, cachepic_t *pic, float width, float height int e0, e1, e2, e3; if (!pic) pic = Draw_CachePic("white"); + // make sure pic is loaded - we don't use the texture here, Mod_Mesh_GetTexture looks up the skinframe by name + Draw_GetPicTexture(pic); if (width == 0) width = pic->width; if (height == 0) height = pic->height; - surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, pic->name, flags, pic->texflags, MATERIALFLAG_VERTEXCOLOR), true); + surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, pic->name, flags, pic->texflags, MATERIALFLAG_WALL | MATERIALFLAG_VERTEXCOLOR | MATERIALFLAG_ALPHAGEN_VERTEX | MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW), true); e0 = Mod_Mesh_IndexForVertex(mod, surf, x , y , 0, 0, 0, -1, s1, t1, 0, 0, r1, g1, b1, a1); e1 = Mod_Mesh_IndexForVertex(mod, surf, x + width, y , 0, 0, 0, -1, s2, t2, 0, 0, r2, g2, b2, a2); e2 = Mod_Mesh_IndexForVertex(mod, surf, x + width, y + height, 0, 0, 0, -1, s4, t4, 0, 0, r4, g4, b4, a4); @@ -1409,7 +1441,7 @@ void DrawQ_Line (float width, float x1, float y1, float x2, float y2, float r, f offsetx = 0.5f * width * vid_conwidth.value / vid.width; offsety = 0; } - surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, "white", 0, 0, MATERIALFLAG_VERTEXCOLOR), true); + surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, "white", 0, 0, MATERIALFLAG_WALL | MATERIALFLAG_VERTEXCOLOR | MATERIALFLAG_ALPHAGEN_VERTEX | MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW), true); e0 = Mod_Mesh_IndexForVertex(mod, surf, x1 - offsetx, y1 - offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha); e1 = Mod_Mesh_IndexForVertex(mod, surf, x2 - offsetx, y2 - offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha); e2 = Mod_Mesh_IndexForVertex(mod, surf, x2 + offsetx, y2 + offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha); @@ -1431,7 +1463,7 @@ void DrawQ_SetClipArea(float x, float y, float width, float height) ih = (int)(0.5 + height * ((float)r_refdef.view.height / vid_conheight.integer)); switch(vid.renderpath) { - case RENDERPATH_GL20: + case RENDERPATH_GL32: case RENDERPATH_GLES2: GL_Scissor(ix, vid.height - iy - ih, iw, ih); break; @@ -1461,7 +1493,6 @@ void DrawQ_RecalcView(void) void DrawQ_FlushUI(void) { - int i; dp_model_t *mod = CL_Mesh_UI(); if (mod->num_surfaces == 0) return; @@ -1472,24 +1503,13 @@ void DrawQ_FlushUI(void) return; } - // TODO: render the mesh using R_Q1BSP_Draw or similar, for full material support. + // this is roughly equivalent to R_Q1BSP_Draw, so the UI can use full material feature set + r_refdef.view.colorscale = 1; + r_textureframe++; // used only by R_GetCurrentTexture GL_DepthMask(false); - R_Mesh_PrepareVertices_Generic_Arrays(mod->surfmesh.num_vertices, mod->surfmesh.data_vertex3f, mod->surfmesh.data_lightmapcolor4f, mod->surfmesh.data_texcoordtexture2f); - for (i = 0; i < mod->num_surfaces; i++) - { - msurface_t *surf = mod->data_surfaces + i; - texture_t *tex = surf->texture; - if (tex->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND) - GL_BlendFunc(tex->customblendfunc[0], tex->customblendfunc[1]); - else if (tex->currentmaterialflags & MATERIALFLAG_ADD) - GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); - else if (tex->currentmaterialflags & MATERIALFLAG_ALPHA) - GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - else - GL_BlendFunc(GL_ONE, GL_ZERO); - R_SetupShader_Generic(tex->currentskinframe->base, NULL, GL_MODULATE, 1, (tex->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND) ? false : true, true, false); - R_Mesh_Draw(surf->num_firstvertex, surf->num_vertices, surf->num_firsttriangle, surf->num_triangles, mod->surfmesh.data_element3i, NULL, 0, mod->surfmesh.data_element3s, NULL, 0); - } + + Mod_Mesh_Finalize(mod); + R_DrawModelSurfaces(&cl_meshentities[MESH_UI].render, false, false, false, false, false, true); Mod_Mesh_Reset(mod); }