X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=gl_draw.c;h=a97d33d9a4064bd44f61a3deb223ddc794cfc8a5;hb=46a67647b115154668877ed632b38d95aac7066d;hp=4f700ff73eb28051994f0989dc34eafaf6385832;hpb=de5bb2274041bd0ea98dae9a93419104b50b5465;p=xonotic%2Fdarkplaces.git diff --git a/gl_draw.c b/gl_draw.c index 4f700ff7..a97d33d9 100644 --- a/gl_draw.c +++ b/gl_draw.c @@ -105,32 +105,37 @@ 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\"): reloading pic due to mismatch on flags\n", path); + goto reload; + } if (!pic->skinframe || !pic->skinframe->base) + { + Con_DPrintf("Draw_CachePic(\"%s\"): reloading pic\n", pic); 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_Printf ("Draw_CachePic(\"%s\"): numcachepics == MAX_CACHED_PICS\n", path); // FIXME: support NULL in callers? return cachepics; // return the first one } + Con_DPrintf("Draw_CachePic(\"%s\"): loading pic\n", path); pic = cachepics + (numcachepics++); memset(pic, 0, sizeof(*pic)); strlcpy (pic->name, path, sizeof(pic->name)); @@ -147,8 +152,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, (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 +207,7 @@ qboolean Draw_IsPicLoaded(cachepic_t *pic) if (pic == NULL) return false; if (pic->autoload && (!pic->skinframe || !pic->skinframe->base)) - pic->skinframe = R_SkinFrame_LoadExternal(pic->name, pic->texflags, false, true); + 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 +217,7 @@ rtexture_t *Draw_GetPicTexture(cachepic_t *pic) if (pic == NULL) return NULL; if (pic->autoload && (!pic->skinframe || !pic->skinframe->base)) - pic->skinframe = R_SkinFrame_LoadExternal(pic->name, pic->texflags, false, true); + 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,7 +231,7 @@ 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) R_SkinFrame_PurgeSkinFrame(pic->skinframe); draw_frame++; } @@ -262,12 +275,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, pixels_bgra, width, height, vid.sRGB2D); + pic->skinframe = R_SkinFrame_LoadInternalBGRA(picname, texflags | TEXF_FORCE_RELOAD, pixels_bgra, width, height, vid.sRGB2D); pic->lastusedframe = draw_frame; return pic; } @@ -744,11 +758,8 @@ void GL_Draw_Init (void) R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown, gl_draw_newmap, NULL, NULL); } -static void _DrawQ_Setup(void) // see R_ResetViewRendering2D +void DrawQ_Start(void) { - if (r_refdef.draw2dstage == 1) - return; - DrawQ_FlushUI(); r_refdef.draw2dstage = 1; R_ResetViewRendering2D_Common(0, NULL, NULL, 0, 0, vid.width, vid.height, vid_conwidth.integer, vid_conheight.integer); } @@ -760,9 +771,10 @@ void DrawQ_Pic(float x, float y, cachepic_t *pic, float width, float height, flo dp_model_t *mod = CL_Mesh_UI(); msurface_t *surf; int e0, e1, e2, e3; - _DrawQ_Setup(); 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) @@ -787,18 +799,19 @@ void DrawQ_RotPic(float x, float y, cachepic_t *pic, float width, float height, dp_model_t *mod = CL_Mesh_UI(); msurface_t *surf; int e0, e1, e2, e3; - _DrawQ_Setup(); 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); - 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), sinaf*(width - org_x) + sinar * (height - org_y), 0, 0, 0, -1, 1, 1, 0, 0, red, green, blue, alpha); - e3 = Mod_Mesh_IndexForVertex(mod, surf, x - cosaf * org_x + cosar * (height - org_y), y - sinaf * org_x + sinar * (height - org_y), 0, 0, 0, -1, 0, 1, 0, 0, red, green, blue, alpha); + 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); + e3 = Mod_Mesh_IndexForVertex(mod, surf, x - cosaf * org_x + cosar * (height - org_y), y - sinaf * org_x + sinar * (height - org_y), 0, 0, 0, -1, 0, 1, 0, 0, red, green, blue, alpha); Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2); Mod_Mesh_AddTriangle(mod, surf, e0, e2, e3); } @@ -1077,8 +1090,6 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma tw = Draw_GetPicWidth(fnt->pic); th = Draw_GetPicHeight(fnt->pic); - _DrawQ_Setup(); - if (!h) h = w; if (!h) { h = w = 1; @@ -1384,9 +1395,10 @@ void DrawQ_SuperPic(float x, float y, cachepic_t *pic, float width, float height dp_model_t *mod = CL_Mesh_UI(); msurface_t *surf; int e0, e1, e2, e3; - _DrawQ_Setup(); 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) @@ -1406,16 +1418,15 @@ void DrawQ_Line (float width, float x1, float y1, float x2, float y2, float r, f msurface_t *surf; int e0, e1, e2, e3; float offsetx, offsety; - _DrawQ_Setup(); // width is measured in real pixels if (fabs(x2 - x1) > fabs(y2 - y1)) { offsetx = 0; - offsety = width * vid_conheight.value / vid.height; + offsety = 0.5f * width * vid_conheight.value / vid.height; } else { - offsetx = width * vid_conwidth.value / vid.width; + 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); @@ -1430,7 +1441,6 @@ void DrawQ_Line (float width, float x1, float y1, float x2, float y2, float r, f void DrawQ_SetClipArea(float x, float y, float width, float height) { int ix, iy, iw, ih; - _DrawQ_Setup(); DrawQ_FlushUI(); // We have to convert the con coords into real coords @@ -1441,23 +1451,10 @@ 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_GL11: - case RENDERPATH_GL13: - case RENDERPATH_GL20: - case RENDERPATH_GLES1: + case RENDERPATH_GL32: case RENDERPATH_GLES2: - case RENDERPATH_SOFT: GL_Scissor(ix, vid.height - iy - ih, iw, ih); break; - case RENDERPATH_D3D9: - GL_Scissor(ix, iy, iw, ih); - break; - case RENDERPATH_D3D10: - Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__); - break; - case RENDERPATH_D3D11: - Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__); - break; } GL_ScissorTest(true); @@ -1466,7 +1463,6 @@ void DrawQ_SetClipArea(float x, float y, float width, float height) void DrawQ_ResetClipArea(void) { DrawQ_FlushUI(); - _DrawQ_Setup(); GL_ScissorTest(false); } @@ -1511,7 +1507,7 @@ void DrawQ_FlushUI(void) 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_SetupShader_Generic(tex->currentskinframe->base, (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); }