}
}
}
- if (updated)
- {
- int count = model->brushq3.num_mergedlightmaps;
- for (i = 0;i < count;i++)
- {
- if (model->brushq3.data_deluxemaps[i])
- R_FlushTexture(model->brushq3.data_deluxemaps[i]);
- if (model->brushq3.data_lightmaps[i])
- R_FlushTexture(model->brushq3.data_lightmaps[i]);
- }
- }
}
// don't do anything if there were no surfaces
if (!numsurfacelist)
R_BuildLightMap(ent, surfaces + j);
}
}
- if (updated)
- {
- int count = model->brushq3.num_mergedlightmaps;
- for (i = 0;i < count;i++)
- {
- if (model->brushq3.data_deluxemaps[i])
- R_FlushTexture(model->brushq3.data_deluxemaps[i]);
- if (model->brushq3.data_lightmaps[i])
- R_FlushTexture(model->brushq3.data_lightmaps[i]);
- }
- }
}
if (update)
for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++)
cvar_t gl_texturecompression_q3bspdeluxemaps = {CVAR_SAVE, "gl_texturecompression_q3bspdeluxemaps", "0", "whether to compress deluxemaps in q3bsp format levels (only levels compiled with q3map2 -deluxe have these)"};
cvar_t gl_texturecompression_sky = {CVAR_SAVE, "gl_texturecompression_sky", "0", "whether to compress sky textures"};
cvar_t gl_texturecompression_lightcubemaps = {CVAR_SAVE, "gl_texturecompression_lightcubemaps", "1", "whether to compress light cubemaps (spotlights and other light projection images)"};
-cvar_t gl_nopartialtextureupdates = {CVAR_SAVE, "gl_nopartialtextureupdates", "0", "use alternate path for dynamic lightmap updates"};
+cvar_t gl_nopartialtextureupdates = {CVAR_SAVE, "gl_nopartialtextureupdates", "1", "use alternate path for dynamic lightmap updates that avoids a possibly slow code path in the driver"};
int gl_filter_min = GL_LINEAR_MIPMAP_LINEAR;
int gl_filter_mag = GL_LINEAR;
void *updatacallback_data;
// --- [11/22/2007 Black]
- // stores backup copy of texture for deferred texture updates (r_nopartialtextureupdates cvar)
+ // stores backup copy of texture for deferred texture updates (gl_nopartialtextureupdates cvar)
unsigned char *bufferpixels;
qboolean buffermodified;
qglBindTexture(gltexturetypeenums[glt->texturetype], oldbindtexnum);CHECKGLERROR
}
-int R_RealGetTexture(rtexture_t *rt)
-{
- if (rt)
- {
- gltexture_t *glt;
- glt = (gltexture_t *)rt;
- if (glt->flags & GLTEXF_DYNAMIC)
- R_UpdateDynamicTexture(glt);
- return glt->texnum;
- }
- else
- return 0;
-}
-
static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int depth, int sides, int flags, textype_t textype, int texturetype, const unsigned char *data, const unsigned int *palette)
{
int i, size;
height = glt->tileheight - y;
if (width < 1 || height < 1)
return;
+ glt->dirty = true;
glt->buffermodified = true;
output += y*outputskip + x*bpp;
for (j = 0;j < height;j++, output += outputskip, input += inputskip)
memcpy(output, input, width*bpp);
- if (!(glt->flags & TEXF_MANUALFLUSHUPDATES))
- R_FlushTexture(rt);
}
else
R_Upload(glt, data, x, y, 0, width, height, 1);
}
-void R_FlushTexture(rtexture_t *rt)
+int R_RealGetTexture(rtexture_t *rt)
{
- gltexture_t *glt;
- if (rt == NULL)
- Host_Error("R_FlushTexture: no texture supplied");
-
- // update part of the texture
- glt = (gltexture_t *)rt;
-
- if (!glt->buffermodified || !glt->bufferpixels)
- return;
- glt->buffermodified = false;
- R_Upload(glt, glt->bufferpixels, 0, 0, 0, glt->tilewidth, glt->tileheight, glt->tiledepth);
+ if (rt)
+ {
+ gltexture_t *glt;
+ glt = (gltexture_t *)rt;
+ if (glt->flags & GLTEXF_DYNAMIC)
+ R_UpdateDynamicTexture(glt);
+ if (glt->buffermodified && glt->bufferpixels)
+ {
+ glt->buffermodified = false;
+ R_Upload(glt, glt->bufferpixels, 0, 0, 0, glt->tilewidth, glt->tileheight, glt->tiledepth);
+ }
+ glt->dirty = false;
+ return glt->texnum;
+ }
+ else
+ return 0;
}
void R_ClearTexture (rtexture_t *rt)
loadmodel->brushq3.num_mergedlightmaps = lightmapnumber + 1;
loadmodel->brushq3.data_lightmaps = Mem_Realloc(loadmodel->mempool, loadmodel->brushq3.data_lightmaps, loadmodel->brushq3.num_mergedlightmaps * sizeof(loadmodel->brushq3.data_lightmaps[0]));
loadmodel->brushq3.data_deluxemaps = Mem_Realloc(loadmodel->mempool, loadmodel->brushq3.data_deluxemaps, loadmodel->brushq3.num_mergedlightmaps * sizeof(loadmodel->brushq3.data_deluxemaps[0]));
- loadmodel->brushq3.data_lightmaps[lightmapnumber] = lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, va("lightmap%i", lightmapnumber), lightmapsize, lightmapsize, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_ALLOWUPDATES | TEXF_MANUALFLUSHUPDATES, NULL);
+ loadmodel->brushq3.data_lightmaps[lightmapnumber] = lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, va("lightmap%i", lightmapnumber), lightmapsize, lightmapsize, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_ALLOWUPDATES, NULL);
if (loadmodel->brushq1.nmaplightdata)
- loadmodel->brushq3.data_deluxemaps[lightmapnumber] = deluxemaptexture = R_LoadTexture2D(loadmodel->texturepool, va("deluxemap%i", lightmapnumber), lightmapsize, lightmapsize, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_ALLOWUPDATES | TEXF_MANUALFLUSHUPDATES, NULL);
+ loadmodel->brushq3.data_deluxemaps[lightmapnumber] = deluxemaptexture = R_LoadTexture2D(loadmodel->texturepool, va("deluxemap%i", lightmapnumber), lightmapsize, lightmapsize, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_ALLOWUPDATES, NULL);
lightmapnumber++;
Mod_AllocLightmap_Reset(&allocState);
Mod_AllocLightmap_Block(&allocState, ssize, tsize, &lightmapx, &lightmapy);
;
if (developer_loading.integer)
Con_Printf("lightmap merge texture #%i is %ix%i (%i of %i used)\n", lightmapindex, mergewidth*size, mergeheight*size, min(j, mergewidth*mergeheight), mergewidth*mergeheight);
- loadmodel->brushq3.data_lightmaps[lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va("lightmap%04i", lightmapindex), mergewidth * size, mergeheight * size, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | (gl_texturecompression_q3bsplightmaps.integer ? TEXF_COMPRESS : TEXF_ALLOWUPDATES | TEXF_MANUALFLUSHUPDATES), NULL);
+ loadmodel->brushq3.data_lightmaps[lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va("lightmap%04i", lightmapindex), mergewidth * size, mergeheight * size, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | (gl_texturecompression_q3bsplightmaps.integer ? TEXF_COMPRESS : TEXF_ALLOWUPDATES), NULL);
if (loadmodel->brushq3.data_deluxemaps)
- loadmodel->brushq3.data_deluxemaps[lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va("deluxemap%04i", lightmapindex), mergewidth * size, mergeheight * size, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | (gl_texturecompression_q3bspdeluxemaps.integer ? TEXF_COMPRESS : TEXF_ALLOWUPDATES | TEXF_MANUALFLUSHUPDATES), NULL);
+ loadmodel->brushq3.data_deluxemaps[lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va("deluxemap%04i", lightmapindex), mergewidth * size, mergeheight * size, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | (gl_texturecompression_q3bspdeluxemaps.integer ? TEXF_COMPRESS : TEXF_ALLOWUPDATES), NULL);
}
mergewidth = R_TextureWidth(loadmodel->brushq3.data_lightmaps[lightmapindex]) / size;
mergeheight = R_TextureHeight(loadmodel->brushq3.data_lightmaps[lightmapindex]) / size;
}
}
- for (i = 0;i < loadmodel->brushq3.num_mergedlightmaps;i++)
- {
- if (loadmodel->brushq3.data_deluxemaps && loadmodel->brushq3.data_deluxemaps[i])
- R_FlushTexture(loadmodel->brushq3.data_deluxemaps[i]);
- if (loadmodel->brushq3.data_lightmaps[i])
- R_FlushTexture(loadmodel->brushq3.data_lightmaps[i]);
- }
-
Mem_Free(convertedpixels);
if(external)
{
#define TEXF_COMPARE 0x00000800
// indicates texture should use lower precision where supported
#define TEXF_LOWPRECISION 0x00001000
-// indicates texture should support R_UpdateTexture
+// indicates texture should support R_UpdateTexture, actual uploads may be delayed until R_Mesh_TexBind if gl_nopartialtextureupdates is on
#define TEXF_ALLOWUPDATES 0x00002000
-// indicates texture should support R_FlushTexture (improving speed on multiple partial updates per draw)
-#define TEXF_MANUALFLUSHUPDATES 0x00004000
// used for checking if textures mismatch
#define TEXF_IMPORTANTBITS (TEXF_ALPHA | TEXF_MIPMAP | TEXF_CLAMP | TEXF_FORCENEAREST | TEXF_FORCELINEAR | TEXF_PICMIP | TEXF_COMPRESS | TEXF_COMPARE | TEXF_LOWPRECISION)
void R_FreeTexture(rtexture_t *rt);
// update a portion of the image data of a texture, used by lightmap updates
-// and procedural textures such as video playback.
-// if TEXF_MANUALFLUSHUPDATES is used, you MUST call R_FlushTexture to apply the updates
+// and procedural textures such as video playback, actual uploads may be
+// delayed by gl_nopartialtextureupdates cvar until R_Mesh_TexBind uses it
void R_UpdateTexture(rtexture_t *rt, const unsigned char *data, int x, int y, int width, int height);
-// if TEXF_MANUALFLUSHUPDATES is used, call this to apply the updates,
-// otherwise this function does nothing
-void R_FlushTexture(rtexture_t *rt);
// returns the renderer dependent texture slot number (call this before each
// use, as a texture might not have been precached)