mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-22 12:01:25 +00:00
Optimise rtlights slightly.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6049 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
8c7c69a4ea
commit
4e172f3507
4 changed files with 111 additions and 22 deletions
|
@ -654,6 +654,7 @@ extern cvar_t r_shadow_realtime_dlight_ambient;
|
|||
extern cvar_t r_shadow_realtime_dlight_diffuse;
|
||||
extern cvar_t r_shadow_realtime_dlight_specular;
|
||||
extern cvar_t r_shadow_realtime_world, r_shadow_realtime_world_shadows, r_shadow_realtime_world_lightmaps, r_shadow_realtime_world_importlightentitiesfrommap;
|
||||
extern float r_shadow_realtime_world_lightmaps_force;
|
||||
extern cvar_t r_shadow_shadowmapping;
|
||||
extern cvar_t r_mirroralpha;
|
||||
extern cvar_t r_wateralpha;
|
||||
|
|
|
@ -784,7 +784,7 @@ static int r_editlights_selected = -1; //the light closest to the cursor
|
|||
static vec3_t r_editlights_cursor; //the position of the crosshair/cursor (new lights will be spawned here)
|
||||
static dlight_t r_editlights_copybuffer; //written by r_editlights_copyinfo, read by r_editlights_pasteinfo. FIXME: use system clipboard?
|
||||
|
||||
qboolean R_ImportRTLights(const char *entlump)
|
||||
qboolean R_ImportRTLights(const char *entlump, int importmode)
|
||||
{
|
||||
typedef enum lighttype_e {LIGHTTYPE_MINUSX, LIGHTTYPE_RECIPX, LIGHTTYPE_RECIPXX, LIGHTTYPE_INFINITE, LIGHTTYPE_LOCALMIN, LIGHTTYPE_RECIPXX2, LIGHTTYPE_SUN} lighttype_t;
|
||||
|
||||
|
@ -870,6 +870,9 @@ qboolean R_ImportRTLights(const char *entlump)
|
|||
InfoBuf_SetStarKey(&targets, targetname, va("%f %f %f", origin[0], origin[1], origin[2]));
|
||||
}
|
||||
|
||||
if (!importmode && !rerelease)
|
||||
return false; //don't make it up from legacy ents.
|
||||
|
||||
for (entnum = 0; ;entnum++)
|
||||
{
|
||||
entlump = COM_Parse(entlump);
|
||||
|
@ -1121,7 +1124,7 @@ qboolean R_ImportRTLights(const char *entlump)
|
|||
else if (entnum == 0 && !strcmp("lightmapbright", key))
|
||||
{
|
||||
//tenebrae compat. this overrides r_shadow_realtime_world_lightmap
|
||||
r_shadow_realtime_world_lightmaps.value = atof(value);
|
||||
r_shadow_realtime_world_lightmaps_force = atof(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1183,7 +1186,7 @@ qboolean R_ImportRTLights(const char *entlump)
|
|||
}
|
||||
|
||||
if (rerelease)
|
||||
r_shadow_realtime_world_lightmaps.value = 1;
|
||||
r_shadow_realtime_world_lightmaps_force = 1;
|
||||
else if (radius < 50) //some mappers insist on many tiny lights. such lights can usually get away with no shadows..
|
||||
pflags |= PFLAGS_NOSHADOW;
|
||||
|
||||
|
@ -1573,8 +1576,9 @@ static void R_ReloadRTLights_f(void)
|
|||
}
|
||||
rtlights_first = RTL_FIRST;
|
||||
rtlights_max = RTL_FIRST;
|
||||
r_shadow_realtime_world_lightmaps_force = -1;
|
||||
if (!strcmp(Cmd_Argv(1), "bsp"))
|
||||
R_ImportRTLights(Mod_GetEntitiesString(cl.worldmodel));
|
||||
R_ImportRTLights(Mod_GetEntitiesString(cl.worldmodel), 1);
|
||||
else if (!strcmp(Cmd_Argv(1), "rtlights"))
|
||||
R_LoadRTLights();
|
||||
else if (!strcmp(Cmd_Argv(1), "statics"))
|
||||
|
@ -1595,8 +1599,13 @@ static void R_ReloadRTLights_f(void)
|
|||
R_StaticEntityToRTLight(i);
|
||||
//otherwise try to import.
|
||||
if (rtlights_first == rtlights_max)
|
||||
R_ImportRTLights(Mod_GetEntitiesString(cl.worldmodel));
|
||||
R_ImportRTLights(Mod_GetEntitiesString(cl.worldmodel), r_shadow_realtime_world_importlightentitiesfrommap.ival);
|
||||
}
|
||||
|
||||
if (r_shadow_realtime_world_lightmaps_force >= 0)
|
||||
r_shadow_realtime_world_lightmaps.value = r_shadow_realtime_world_lightmaps_force;
|
||||
else
|
||||
r_shadow_realtime_world_lightmaps.value = atof(r_shadow_realtime_world_lightmaps.string);
|
||||
}
|
||||
|
||||
//-1 for arg error
|
||||
|
|
|
@ -57,6 +57,7 @@ cvar_t r_shadow_scissor = CVARD("r_shadow_scissor", "1", "constrains stencil sha
|
|||
cvar_t r_shadow_realtime_world = CVARFD ("r_shadow_realtime_world", "0", CVAR_ARCHIVE, "Enables the use of static/world realtime lights.");
|
||||
cvar_t r_shadow_realtime_world_shadows = CVARF ("r_shadow_realtime_world_shadows", "1", CVAR_ARCHIVE);
|
||||
cvar_t r_shadow_realtime_world_lightmaps = CVARFD ("r_shadow_realtime_world_lightmaps", "0", 0, "Specifies how much of the map's normal lightmap to retain when using world realtime lights. 0 completely replaces lighting.");
|
||||
float r_shadow_realtime_world_lightmaps_force;
|
||||
cvar_t r_shadow_realtime_world_importlightentitiesfrommap = CVARFD ("r_shadow_realtime_world_importlightentitiesfrommap", "0", CVAR_ARCHIVE, "Controls default loading of map-based realtime lights.\n0: Load explicit .rtlight files only.\n1: Load explicit lights then try fallback to parsing the entities lump.\n2: Load only the entities lump.");
|
||||
cvar_t r_shadow_realtime_dlight = CVARAFD ("r_shadow_realtime_dlight", "1", "r_shadow_realtime_dynamic", CVAR_ARCHIVE, "Enables the use of dynamic realtime lights, allowing explosions to use bumpmaps etc properly.");
|
||||
cvar_t r_shadow_realtime_dlight_shadows = CVARFD ("r_shadow_realtime_dlight_shadows", "1", CVAR_ARCHIVE, "Allows dynamic realtime lights to cast shadows as they move.");
|
||||
|
@ -103,6 +104,8 @@ void Sh_Shutdown(void)
|
|||
|
||||
typedef struct {
|
||||
unsigned int count;
|
||||
unsigned int faceidxcount;
|
||||
unsigned int faceidxfirst;
|
||||
unsigned int max;
|
||||
texture_t *tex;
|
||||
vbo_t *vbo;
|
||||
|
@ -137,7 +140,8 @@ typedef struct shadowmesh_s
|
|||
struct vk_shadowbuffer *vkbuffer;
|
||||
#endif
|
||||
#ifdef GLQUAKE
|
||||
GLuint vebo[2];
|
||||
GLuint vefbo[3];
|
||||
qboolean havefaceebo;
|
||||
#endif
|
||||
#ifdef D3D9QUAKE
|
||||
IDirect3DVertexBuffer9 *d3d9_vbuffer;
|
||||
|
@ -366,6 +370,7 @@ static void SHM_Shadow_Cache_Surface(msurface_t *surf)
|
|||
}
|
||||
sh_shmesh->batches[i].s[sh_shmesh->batches[i].count] = surf->mesh;
|
||||
sh_shmesh->batches[i].count++;
|
||||
sh_shmesh->batches[i].faceidxcount += surf->mesh->numindexes;
|
||||
}
|
||||
|
||||
static void SHM_Shadow_Cache_Leaf(mleaf_t *leaf)
|
||||
|
@ -401,9 +406,11 @@ static void SH_FreeShadowMesh_(shadowmesh_t *sm)
|
|||
#ifdef GLQUAKE
|
||||
case QR_OPENGL:
|
||||
if (qglDeleteBuffersARB)
|
||||
qglDeleteBuffersARB(2, sm->vebo);
|
||||
sm->vebo[0] = 0;
|
||||
sm->vebo[1] = 0;
|
||||
qglDeleteBuffersARB(3, sm->vefbo);
|
||||
sm->vefbo[0] = 0;
|
||||
sm->vefbo[1] = 0;
|
||||
sm->vefbo[2] = 0;
|
||||
sm->havefaceebo = false;
|
||||
break;
|
||||
#endif
|
||||
#ifdef VKQUAKE
|
||||
|
@ -521,6 +528,7 @@ static void SHM_BeginShadowMesh(dlight_t *dl, int type)
|
|||
sh_shmesh->litleaves = Z_Malloc(lb);
|
||||
}
|
||||
}
|
||||
sh_shmesh->havefaceebo = false;
|
||||
sh_shmesh->maxverts = 0;
|
||||
sh_shmesh->numverts = 0;
|
||||
sh_shmesh->maxindicies = 0;
|
||||
|
@ -547,8 +555,47 @@ static void SHM_BeginShadowMesh(dlight_t *dl, int type)
|
|||
for (i = 0; i < sh_shmesh->numbatches; i++)
|
||||
{
|
||||
sh_shmesh->batches[i].count = 0;
|
||||
sh_shmesh->batches[i].faceidxcount = 0;
|
||||
}
|
||||
}
|
||||
static size_t SHM_GenWorldFaceIndexes(index_t **outindexes)
|
||||
{
|
||||
size_t count = 0, b, m, i;
|
||||
index_t *out = *outindexes = NULL;
|
||||
mesh_t *surf;
|
||||
shadowmeshbatch_t *batch;
|
||||
size_t tmp;
|
||||
|
||||
if (sh_shmesh == &sh_tempshmesh)
|
||||
{
|
||||
for (b = 0; b < sh_shmesh->numbatches; b++)
|
||||
sh_shmesh->batches[b].faceidxcount = 0;
|
||||
|
||||
*outindexes = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (b = 0; b < sh_shmesh->numbatches; b++)
|
||||
count+= sh_shmesh->batches[b].faceidxcount;
|
||||
out = *outindexes = (void*fte_restrict)BZ_Malloc(count * sizeof(*out));
|
||||
|
||||
for (b = 0, batch = sh_shmesh->batches; b < sh_shmesh->numbatches; b++, batch++)
|
||||
{
|
||||
batch->faceidxfirst = out-*outindexes;
|
||||
for (m = 0; m < batch->count; m++)
|
||||
{
|
||||
surf = batch->s[m];
|
||||
for (i = 0; i < surf->numindexes; i++)
|
||||
{
|
||||
tmp = surf->vbofirstvert + surf->indexes[i];
|
||||
if (tmp > MAX_INDICIES)
|
||||
Sys_Error("Too many indexes\n");
|
||||
*out++ = surf->vbofirstvert + surf->indexes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
static struct shadowmesh_s *SHM_FinishShadowMesh(dlight_t *dl)
|
||||
{
|
||||
if (sh_shmesh != &sh_tempshmesh || 1)
|
||||
|
@ -564,15 +611,28 @@ static struct shadowmesh_s *SHM_FinishShadowMesh(dlight_t *dl)
|
|||
case QR_OPENGL:
|
||||
if (!qglGenBuffersARB)
|
||||
return sh_shmesh;
|
||||
if (!sh_shmesh->vebo[0])
|
||||
qglGenBuffersARB(2, sh_shmesh->vebo);
|
||||
{ //generate a per-face buffer.
|
||||
index_t *faceindexes;
|
||||
size_t faceindexcount = SHM_GenWorldFaceIndexes(&faceindexes);
|
||||
|
||||
GL_DeselectVAO();
|
||||
GL_SelectVBO(sh_shmesh->vebo[0]);
|
||||
qglBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(*sh_shmesh->verts) * sh_shmesh->numverts, sh_shmesh->verts, GL_STATIC_DRAW_ARB);
|
||||
if (!sh_shmesh->vefbo[0])
|
||||
qglGenBuffersARB(3, sh_shmesh->vefbo);
|
||||
|
||||
GL_SelectEBO(sh_shmesh->vebo[1]);
|
||||
qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(*sh_shmesh->indicies) * sh_shmesh->numindicies, sh_shmesh->indicies, GL_STATIC_DRAW_ARB);
|
||||
GL_DeselectVAO();
|
||||
GL_SelectVBO(sh_shmesh->vefbo[0]);
|
||||
qglBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(*sh_shmesh->verts) * sh_shmesh->numverts, sh_shmesh->verts, GL_STATIC_DRAW_ARB);
|
||||
|
||||
if (faceindexes)
|
||||
{
|
||||
GL_SelectEBO(sh_shmesh->vefbo[2]);
|
||||
qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(*faceindexes) * faceindexcount, faceindexes, GL_STATIC_DRAW_ARB);
|
||||
BZ_Free(faceindexes);
|
||||
sh_shmesh->havefaceebo = true;
|
||||
}
|
||||
|
||||
GL_SelectEBO(sh_shmesh->vefbo[1]);
|
||||
qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(*sh_shmesh->indicies) * sh_shmesh->numindicies, sh_shmesh->indicies, GL_STATIC_DRAW_ARB);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef VKQUAKE
|
||||
|
@ -2349,7 +2409,7 @@ static void Sh_GenShadowFace(dlight_t *l, vec3_t axis[3], int lighttype, shadowm
|
|||
qglEnable(GL_DEPTH_CLAMP_ARB);
|
||||
GL_CullFace(SHADER_CULL_FRONT);
|
||||
if (smesh)
|
||||
GLBE_RenderShadowBuffer(smesh->numverts, smesh->vebo[0], smesh->verts, smesh->numindicies, smesh->vebo[1], smesh->indicies);
|
||||
GLBE_RenderShadowBuffer(smesh->numverts, smesh->vefbo[0], smesh->verts, smesh->numindicies, smesh->vefbo[1], smesh->indicies);
|
||||
break;
|
||||
#endif
|
||||
#ifdef VKQUAKE
|
||||
|
@ -2988,7 +3048,22 @@ static void Sh_DrawEntLighting(dlight_t *light, vec3_t colour, qbyte *pvs)
|
|||
if (shader->flags & (SHADER_NODLIGHT|SHADER_NODRAW|SHADER_SKY))
|
||||
continue;
|
||||
//FIXME: it should be worth building a dedicated ebo, for static ones
|
||||
BE_DrawMesh_List(shader, sm->batches[tno].count, sm->batches[tno].s, cl.worldmodel->shadowbatches[tno].vbo, NULL, 0);
|
||||
if (sm->batches[tno].faceidxcount && !(shader->flags & SHADER_NEEDSARRAYS) && sm->havefaceebo)
|
||||
{
|
||||
mesh_t unimesh = {0};
|
||||
mesh_t *unimeshptr = &unimesh;
|
||||
vboarray_t oldidx = cl.worldmodel->shadowbatches[tno].vbo->indicies;
|
||||
unimesh.numindexes = sm->batches[tno].faceidxcount;
|
||||
unimesh.numvertexes = cl.worldmodel->shadowbatches[tno].vbo->vertcount;
|
||||
unimesh.vbofirstelement = sm->batches[tno].faceidxfirst;
|
||||
cl.worldmodel->shadowbatches[tno].vbo->indicies.gl.vbo = sm->vefbo[2];
|
||||
cl.worldmodel->shadowbatches[tno].vbo->indicies.gl.addr = NULL;
|
||||
|
||||
BE_DrawMesh_List(shader, 1, &unimeshptr, cl.worldmodel->shadowbatches[tno].vbo, NULL, 0);
|
||||
cl.worldmodel->shadowbatches[tno].vbo->indicies = oldidx;
|
||||
}
|
||||
else
|
||||
BE_DrawMesh_List(shader, sm->batches[tno].count, sm->batches[tno].s, cl.worldmodel->shadowbatches[tno].vbo, NULL, 0);
|
||||
RQuantAdd(RQUANT_LITFACES, sm->batches[tno].count);
|
||||
}
|
||||
|
||||
|
@ -3182,7 +3257,7 @@ static void Sh_DrawStencilLightShadows(dlight_t *dl, qbyte *lvis, qbyte *vvis, q
|
|||
#endif
|
||||
#ifdef GLQUAKE
|
||||
case QR_OPENGL:
|
||||
GLBE_RenderShadowBuffer(sm->numverts, sm->vebo[0], sm->verts, sm->numindicies, sm->vebo[1], sm->indicies);
|
||||
GLBE_RenderShadowBuffer(sm->numverts, sm->vefbo[0], sm->verts, sm->numindicies, sm->vefbo[1], sm->indicies);
|
||||
break;
|
||||
#endif
|
||||
#ifdef VKQUAKE
|
||||
|
@ -3747,6 +3822,7 @@ void Sh_PreGenerateLights(void)
|
|||
if ((r_shadow_realtime_dlight.ival || r_shadow_realtime_world.ival) && rtlights_max == RTL_FIRST)
|
||||
{
|
||||
qboolean okay = false;
|
||||
r_shadow_realtime_world_lightmaps_force = -1;
|
||||
if (!okay && r_shadow_realtime_world_importlightentitiesfrommap.ival <= 1)
|
||||
okay |= R_LoadRTLights();
|
||||
if (!okay)
|
||||
|
@ -3755,8 +3831,8 @@ void Sh_PreGenerateLights(void)
|
|||
R_StaticEntityToRTLight(i);
|
||||
okay |= rtlights_max != RTL_FIRST;
|
||||
}
|
||||
if (!okay && r_shadow_realtime_world_importlightentitiesfrommap.ival >= 1)
|
||||
okay |= R_ImportRTLights(Mod_GetEntitiesString(cl.worldmodel));
|
||||
if (!okay)
|
||||
okay |= R_ImportRTLights(Mod_GetEntitiesString(cl.worldmodel), r_shadow_realtime_world_importlightentitiesfrommap.ival);
|
||||
if (!okay && r_shadow_realtime_world.ival && r_shadow_realtime_world_lightmaps.value < 0.5)
|
||||
{
|
||||
r_shadow_realtime_world_lightmaps.value = 1;
|
||||
|
@ -3772,6 +3848,9 @@ void Sh_PreGenerateLights(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (r_shadow_realtime_world_lightmaps_force >= 0)
|
||||
r_shadow_realtime_world_lightmaps.value = r_shadow_realtime_world_lightmaps_force;
|
||||
|
||||
ignoreflags = (r_shadow_realtime_world.ival?LFLAG_REALTIMEMODE:0)
|
||||
| (r_shadow_realtime_dlight.ival?LFLAG_NORMALMODE:0);
|
||||
|
||||
|
|
|
@ -392,7 +392,7 @@ void GLR_MarkQ2Lights (dlight_t *light, int bit, mnode_t *node);
|
|||
#endif
|
||||
void GLQ3_LightGrid(model_t *mod, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
|
||||
qboolean R_LoadRTLights(void);
|
||||
qboolean R_ImportRTLights(const char *entlump);
|
||||
qboolean R_ImportRTLights(const char *entlump, int importmode);
|
||||
|
||||
//doom
|
||||
#ifdef MAP_DOOM
|
||||
|
|
Loading…
Reference in a new issue