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)
+ {
+ 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_Printf ("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));
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)
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;
}
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;
}
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++;
}
{
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_Printf("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_Printf ("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_Printf("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));
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;
{
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;
}
}
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)
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)
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)
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;
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);
}