From: havoc Date: Mon, 9 Apr 2018 04:39:19 +0000 (+0000) Subject: Refactored R_UpdateEntityLighting to CL_UpdateEntityShading, which sets fields like... X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=4e1f3f76d5fe7befe20034a730630c314d45956b;p=xonotic%2Fdarkplaces.git Refactored R_UpdateEntityLighting to CL_UpdateEntityShading, which sets fields like ent->render_modellight_ambient. Added texture->render_modellight_ambient and similar fields which concretely define how the material is to be rendered, so all of the various tweaks and modifiers are no longer buried in R_SetupShader_Surface which has now been refactored heavily. Removed R_LightPoint as it's really not necessary - this change will make lit particles a little bit slower as R_CompleteLightPoint is a slightly more expensive function. Refactored R_CompleteLightPoint to have more consistent code, changed the final color math so that it passes q1bsp/q2bsp lighting through unmodified. Changed shading of tag_entity attachments - they now use the root entity's origin for shading, this fixes r_shadows where the shadows could go in different directions on CSQC entities (r_shadows code already contained a hack to work around this problem for network entities). Renamed r_refdef.lightmapintensity and ambient to r_refdef.scene.lightmapintensity and ambientintensity. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12376 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/cl_main.c b/cl_main.c index d5707029..8753a5eb 100644 --- a/cl_main.c +++ b/cl_main.c @@ -2406,14 +2406,14 @@ void CL_MeshEntities_Init(void) ent->state_current.active = true; ent->render.model = cl_meshentitymodels + i; ent->render.alpha = 1; - ent->render.flags = RENDER_SHADOW | RENDER_LIGHT; + ent->render.flags = RENDER_SHADOW | RENDER_LIGHT | RENDER_CUSTOMIZEDMODELLIGHT; ent->render.framegroupblend[0].lerp = 1; ent->render.frameblend[0].lerp = 1; VectorSet(ent->render.colormod, 1, 1, 1); VectorSet(ent->render.glowmod, 1, 1, 1); - VectorSet(ent->render.modellight_ambient, 1, 1, 1); - VectorSet(ent->render.modellight_diffuse, 0, 0, 0); - VectorSet(ent->render.modellight_lightdir, 0, 0, 1); + VectorSet(ent->render.custommodellight_ambient, 1, 1, 1); + VectorSet(ent->render.custommodellight_diffuse, 0, 0, 0); + VectorSet(ent->render.custommodellight_lightdir, 0, 0, 1); Matrix4x4_CreateIdentity(&ent->render.matrix); CL_UpdateRenderEntity(&ent->render); } @@ -2451,6 +2451,221 @@ void CL_MeshEntities_Shutdown(void) { } +extern cvar_t r_overheadsprites_pushback; +extern cvar_t r_fullbright_directed_pitch_relative; +extern cvar_t r_fullbright_directed_pitch; +extern cvar_t r_fullbright_directed_ambient; +extern cvar_t r_fullbright_directed_diffuse; +extern cvar_t r_fullbright_directed; +extern cvar_t r_equalize_entities_minambient; +extern cvar_t r_equalize_entities_to; +extern cvar_t r_equalize_entities_by; +extern cvar_t r_hdr_glowintensity; + +static void CL_UpdateEntityShading_GetDirectedFullbright(vec3_t ambient, vec3_t diffuse, vec3_t worldspacenormal) +{ + vec3_t angles; + + VectorSet(ambient, r_fullbright_directed_ambient.value, r_fullbright_directed_ambient.value, r_fullbright_directed_ambient.value); + VectorSet(diffuse, r_fullbright_directed_diffuse.value, r_fullbright_directed_diffuse.value, r_fullbright_directed_diffuse.value); + + // Use cl.viewangles and not r_refdef.view.forward here so it is the + // same for all stereo views, and to better handle pitches outside + // [-90, 90] (in_pitch_* cvars allow that). + VectorCopy(cl.viewangles, angles); + if (r_fullbright_directed_pitch_relative.integer) { + angles[PITCH] += r_fullbright_directed_pitch.value; + } + else { + angles[PITCH] = r_fullbright_directed_pitch.value; + } + AngleVectors(angles, worldspacenormal, NULL, NULL); + VectorNegate(worldspacenormal, worldspacenormal); +} + +static void CL_UpdateEntityShading_Entity(entity_render_t *ent) +{ + float shadingorigin[3], f, fa, fd, fdd, a[3], c[3], dir[3]; + int q; + + for (q = 0; q < 3; q++) + a[q] = c[q] = dir[q] = 0; + + ent->render_modellight_forced = false; + ent->render_rtlight_disabled = false; + + // pick an appropriate value for render_modellight_origin - if this is an + // attachment we want to use the parent's render_modellight_origin so that + // shading is the same (also important for r_shadows to cast shadows in the + // same direction) + if (VectorLength2(ent->custommodellight_origin)) + { + // CSQC entities always provide this (via CL_GetTagMatrix) + for (q = 0; q < 3; q++) + shadingorigin[q] = ent->custommodellight_origin[q]; + } + else if (ent->entitynumber > 0 && ent->entitynumber < cl.num_entities) + { + // network entity - follow attachment chain back to a root entity, + int entnum = ent->entitynumber, recursion; + for (recursion = 32; recursion > 0; --recursion) + { + int parentnum = cl.entities[entnum].state_current.tagentity; + if (parentnum < 1 || parentnum >= cl.num_entities || !cl.entities_active[parentnum]) + break; + entnum = parentnum; + } + // grab the root entity's origin + Matrix4x4_OriginFromMatrix(&cl.entities[entnum].render.matrix, shadingorigin); + } + else + { + // not a CSQC entity (which sets custommodellight_origin), not a network + // entity - so it's probably not attached to anything + Matrix4x4_OriginFromMatrix(&ent->matrix, shadingorigin); + } + + if (!(ent->flags & RENDER_LIGHT) || r_fullbright.integer) + { + // intentionally EF_FULLBRIGHT entity + // the only type that is not scaled by r_refdef.scene.lightmapintensity + // CSQC can still provide its own customized modellight values + ent->render_rtlight_disabled = true; + ent->render_modellight_forced = true; + if (ent->flags & RENDER_CUSTOMIZEDMODELLIGHT) + { + // custom colors provided by CSQC + for (q = 0; q < 3; q++) + { + a[q] = ent->custommodellight_ambient[q]; + c[q] = ent->custommodellight_diffuse[q]; + dir[q] = ent->custommodellight_lightdir[q]; + } + } + else if (r_fullbright_directed.integer) + CL_UpdateEntityShading_GetDirectedFullbright(a, c, dir); + else + for (q = 0; q < 3; q++) + a[q] = 1; + } + else + { + // fetch the lighting from the worldmodel data + + // CSQC can provide its own customized modellight values + if (ent->flags & RENDER_CUSTOMIZEDMODELLIGHT) + { + ent->render_modellight_forced = true; + for (q = 0; q < 3; q++) + { + a[q] = ent->custommodellight_ambient[q]; + c[q] = ent->custommodellight_diffuse[q]; + dir[q] = ent->custommodellight_lightdir[q]; + } + } + else if (ent->model->type == mod_sprite && !(ent->model->data_textures[0].basematerialflags & MATERIALFLAG_FULLBRIGHT)) + { + if (ent->model->sprite.sprnum_type == SPR_OVERHEAD) // apply offset for overhead sprites + shadingorigin[2] = shadingorigin[2] + r_overheadsprites_pushback.value; + R_CompleteLightPoint(a, c, dir, shadingorigin, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT, r_refdef.scene.lightmapintensity, r_refdef.scene.ambientintensity); + ent->render_modellight_forced = true; + ent->render_rtlight_disabled = true; + } + else if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->lit && r_refdef.scene.worldmodel->brush.LightPoint) + R_CompleteLightPoint(a, c, dir, shadingorigin, LP_LIGHTMAP, r_refdef.scene.lightmapintensity, r_refdef.scene.ambientintensity); + else if (r_fullbright_directed.integer) + CL_UpdateEntityShading_GetDirectedFullbright(a, c, dir); + else + R_CompleteLightPoint(a, c, dir, shadingorigin, LP_LIGHTMAP, r_refdef.scene.lightmapintensity, r_refdef.scene.ambientintensity); + + if (ent->flags & RENDER_EQUALIZE) + { + // first fix up ambient lighting... + if (r_equalize_entities_minambient.value > 0) + { + fd = 0.299f * ent->render_modellight_diffuse[0] + 0.587f * ent->render_modellight_diffuse[1] + 0.114f * ent->render_modellight_diffuse[2]; + if (fd > 0) + { + fa = (0.299f * ent->render_modellight_ambient[0] + 0.587f * ent->render_modellight_ambient[1] + 0.114f * ent->render_modellight_ambient[2]); + if (fa < r_equalize_entities_minambient.value * fd) + { + // solve: + // fa'/fd' = minambient + // fa'+0.25*fd' = fa+0.25*fd + // ... + // fa' = fd' * minambient + // fd'*(0.25+minambient) = fa+0.25*fd + // ... + // fd' = (fa+0.25*fd) * 1 / (0.25+minambient) + // fa' = (fa+0.25*fd) * minambient / (0.25+minambient) + // ... + fdd = (fa + 0.25f * fd) / (0.25f + r_equalize_entities_minambient.value); + f = fdd / fd; // f>0 because all this is additive; f<1 because fdd 0 && r_equalize_entities_by.value != 0) + { + fa = 0.299f * a[0] + 0.587f * a[1] + 0.114f * a[2]; + fd = 0.299f * c[0] + 0.587f * c[1] + 0.114f * c[2]; + f = fa + 0.25 * fd; + if (f > 0) + { + // adjust brightness and saturation to target + float l2 = r_equalize_entities_by.value, l1 = 1 - l2; + for (q = 0; q < 3; q++) + { + a[q] = l1 * a[q] + l2 * (fa / f); + c[q] = l1 * c[q] + l2 * (fd / f); + } + } + } + } + } + + for (q = 0; q < 3; q++) + { + ent->render_fullbright[q] = ent->colormod[q]; + ent->render_glowmod[q] = ent->glowmod[q] * r_hdr_glowintensity.value; + ent->render_modellight_ambient[q] = a[q] * ent->colormod[q]; + ent->render_modellight_diffuse[q] = c[q] * ent->colormod[q]; + ent->render_modellight_specular[q] = c[q]; + ent->render_modellight_lightdir[q] = dir[q]; + ent->render_lightmap_ambient[q] = ent->colormod[q] * r_refdef.scene.ambientintensity; + ent->render_lightmap_diffuse[q] = ent->colormod[q] * r_refdef.scene.lightmapintensity; + ent->render_lightmap_specular[q] = r_refdef.scene.lightmapintensity; + ent->render_rtlight_diffuse[q] = ent->colormod[q]; + ent->render_rtlight_specular[q] = 1; + } + + // these flags disable code paths, make sure it's obvious if they're ignored by storing 0 1 2 + if (ent->render_modellight_forced) + for (q = 0; q < 3; q++) + ent->render_lightmap_ambient[q] = ent->render_lightmap_diffuse[q] = ent->render_lightmap_specular[q] = q; + if (ent->render_rtlight_disabled) + for (q = 0; q < 3; q++) + ent->render_rtlight_diffuse[q] = ent->render_rtlight_specular[q] = q; + + if (VectorLength2(ent->render_modellight_lightdir) == 0) + VectorSet(ent->render_modellight_lightdir, 0, 0, 1); // have to set SOME valid vector here + VectorNormalize(ent->render_modellight_lightdir); +} + + +void CL_UpdateEntityShading(void) +{ + int i; + CL_UpdateEntityShading_Entity(r_refdef.scene.worldentity); + for (i = 0; i < r_refdef.scene.numentities; i++) + CL_UpdateEntityShading_Entity(r_refdef.scene.entities[i]); +} + /* =========== CL_Shutdown diff --git a/cl_particles.c b/cl_particles.c index 5e873998..9d64080b 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -2723,10 +2723,14 @@ static void R_DrawParticle_TransparentCallback(const entity_render_t *ent, const // note: lighting is not cheap! if (particletype[p->typeindex].lighting) { + float a[3], c[3], dir[3]; vecorg[0] = p->org[0]; vecorg[1] = p->org[1]; vecorg[2] = p->org[2]; - R_LightPoint(c4f, vecorg, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT); + R_CompleteLightPoint(a, c, dir, vecorg, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT, r_refdef.scene.lightmapintensity, r_refdef.scene.ambientintensity); + c4f[0] = p->color[0] * colormultiplier[0] * (a[0] + 0.25f * c[0]); + c4f[1] = p->color[1] * colormultiplier[1] * (a[1] + 0.25f * c[1]); + c4f[2] = p->color[2] * colormultiplier[2] * (a[2] + 0.25f * c[2]); } // mix in the fog color if (r_refdef.fogenabled) diff --git a/cl_screen.c b/cl_screen.c index 8ed18a25..e59c6ef0 100644 --- a/cl_screen.c +++ b/cl_screen.c @@ -1895,6 +1895,7 @@ static void R_Envmap_f (void) buffer1 = (unsigned char *)Mem_Alloc(tempmempool, size * size * 4); buffer2 = (unsigned char *)Mem_Alloc(tempmempool, size * size * 3); + CL_UpdateEntityShading(); for (j = 0;j < 12;j++) { dpsnprintf(filename, sizeof(filename), "env/%s%s.tga", basename, envmapinfo[j].name); @@ -2187,7 +2188,10 @@ static void SCR_DrawScreen (void) if (cl.csqc_loaded) CL_VM_UpdateView(r_stereo_side ? 0.0 : max(0.0, cl.time - cl.oldtime)); else + { + CL_UpdateEntityShading(); R_RenderView(); + } } if (!r_stereo_sidebyside.integer && !r_stereo_horizontal.integer && !r_stereo_vertical.integer) diff --git a/client.h b/client.h index 5486b1bf..6be9d5a5 100644 --- a/client.h +++ b/client.h @@ -573,10 +573,37 @@ typedef struct entity_render_s int animcache_skeletaltransform3x4offset; int animcache_skeletaltransform3x4size; - // current lighting from map (updated ONLY by client code, not renderer) - vec3_t modellight_ambient; - vec3_t modellight_diffuse; // q3bsp - vec3_t modellight_lightdir; // q3bsp + // CL_UpdateEntityShading reads these fields + // used only if RENDER_CUSTOMIZEDMODELLIGHT is set + vec3_t custommodellight_ambient; + vec3_t custommodellight_diffuse; + vec3_t custommodellight_lightdir; + // CSQC entities get their shading from the root of their attachment chain + float custommodellight_origin[3]; + + // derived lighting parameters (CL_UpdateEntityShading) + + // used by MATERIALFLAG_FULLBRIGHT which is MATERIALFLAG_MODELLIGHT with + // this as ambient color, along with MATERIALFLAG_NORTLIGHT + float render_fullbright[3]; + // color tint for the base pass glow textures if any + float render_glowmod[3]; + // MATERIALFLAG_MODELLIGHT uses these parameters + float render_modellight_ambient[3]; + float render_modellight_diffuse[3]; + float render_modellight_lightdir[3]; + float render_modellight_specular[3]; + // lightmap rendering (not MATERIALFLAG_MODELLIGHT) + float render_lightmap_ambient[3]; + float render_lightmap_diffuse[3]; + float render_lightmap_specular[3]; + // rtlights use these colors for the materials on this entity + float render_rtlight_diffuse[3]; + float render_rtlight_specular[3]; + // ignore lightmap and use lightgrid on this entity (e.g. FULLBRIGHT) + qboolean render_modellight_forced; + // do not process per pixel lights on this entity at all (like MATERIALFLAG_NORTLIGHT) + qboolean render_rtlight_disabled; // storage of decals on this entity // (note: if allowdecals is set, be sure to call R_DecalSystem_Reset on removal!) @@ -1886,7 +1913,12 @@ typedef struct r_refdef_scene_s { // controls intensity lightmap layers unsigned short lightstylevalue[MAX_LIGHTSTYLES]; // 8.8 fraction of base light value - float ambient; + // adds brightness to the whole scene, separate from lightmapintensity + // see CL_UpdateEntityShading + float ambientintensity; + // brightness of lightmap and modellight lighting on materials + // see CL_UpdateEntityShading + float lightmapintensity; qboolean rtworld; qboolean rtworldshadows; @@ -1956,9 +1988,6 @@ typedef struct r_refdef_s // true during envmap command capture qboolean envmap; - // brightness of world lightmaps and related lighting - // (often reduced when world rtlights are enabled) - float lightmapintensity; // whether to draw world lights realtime, dlights realtime, and their shadows float polygonfactor; float polygonoffset; @@ -2032,6 +2061,7 @@ extern const char *cl_meshentitynames[NUM_MESHENTITIES]; #define CL_Mesh_UI() (&cl_meshentitymodels[MESH_UI]) void CL_MeshEntities_AddToScene(void); void CL_MeshEntities_Reset(void); +void CL_UpdateEntityShading(void); void CL_NewFrameReceived(int num); void CL_ParseEntityLump(char *entitystring); diff --git a/clvm_cmds.c b/clvm_cmds.c index f15abe5d..e6cb562f 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -696,17 +696,12 @@ static void VM_CL_getlight (prvm_prog_t *prog) { vec3_t ambientcolor, diffusecolor, diffusenormal; vec3_t p; + int flags = prog->argc >= 2 ? PRVM_G_FLOAT(OFS_PARM1) : LP_LIGHTMAP; VM_SAFEPARMCOUNTRANGE(1, 3, VM_CL_getlight); VectorCopy(PRVM_G_VECTOR(OFS_PARM0), p); - VectorClear(ambientcolor); - VectorClear(diffusecolor); - VectorClear(diffusenormal); - if (prog->argc >= 2) - R_CompleteLightPoint(ambientcolor, diffusecolor, diffusenormal, p, PRVM_G_FLOAT(OFS_PARM1)); - else if (cl.worldmodel && cl.worldmodel->brush.LightPoint) - cl.worldmodel->brush.LightPoint(cl.worldmodel, p, ambientcolor, diffusecolor, diffusenormal); + R_CompleteLightPoint(ambientcolor, diffusecolor, diffusenormal, p, flags, r_refdef.scene.lightmapintensity, r_refdef.scene.ambientintensity); VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN)); if (PRVM_clientglobalvector(getlight_ambient)) VectorCopy(ambientcolor, PRVM_clientglobalvector(getlight_ambient)); @@ -2453,7 +2448,7 @@ static int CL_GetEntityLocalTagMatrix(prvm_prog_t *prog, prvm_edict_t *ent, int extern cvar_t cl_bob; extern cvar_t cl_bobcycle; extern cvar_t cl_bobup; -int CL_GetTagMatrix (prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *ent, int tagindex) +int CL_GetTagMatrix (prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *ent, int tagindex, prvm_vec_t *shadingorigin) { int ret; int attachloop; @@ -2526,6 +2521,16 @@ int CL_GetTagMatrix (prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *ent, int Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4)); } */ + + // return the origin of the view + if (shadingorigin) + Matrix4x4_OriginFromMatrix(&r_refdef.view.matrix, shadingorigin); + } + else + { + // return the origin of the root entity in the chain + if (shadingorigin) + Matrix4x4_OriginFromMatrix(out, shadingorigin); } return 0; } @@ -2582,7 +2587,7 @@ static void VM_CL_gettaginfo (prvm_prog_t *prog) e = PRVM_G_EDICT(OFS_PARM0); tagindex = (int)PRVM_G_FLOAT(OFS_PARM1); - returncode = CL_GetTagMatrix(prog, &tag_matrix, e, tagindex); + returncode = CL_GetTagMatrix(prog, &tag_matrix, e, tagindex, NULL); Matrix4x4_ToVectors(&tag_matrix, forward, left, up, origin); VectorCopy(forward, PRVM_clientglobalvector(v_forward)); VectorScale(left, -1, PRVM_clientglobalvector(v_right)); @@ -3230,7 +3235,7 @@ static void VM_CL_GetEntity (prvm_prog_t *prog) VectorAdd(cl.entities[entnum].render.maxs, org, PRVM_G_VECTOR(OFS_RETURN)); break; case 16: // light - VectorMA(cl.entities[entnum].render.modellight_ambient, 0.5, cl.entities[entnum].render.modellight_diffuse, PRVM_G_VECTOR(OFS_RETURN)); + VectorMA(cl.entities[entnum].render.render_modellight_ambient, 0.5, cl.entities[entnum].render.render_modellight_diffuse, PRVM_G_VECTOR(OFS_RETURN)); break; default: PRVM_G_FLOAT(OFS_RETURN) = 0; @@ -3266,6 +3271,7 @@ static void VM_CL_R_RenderScene (prvm_prog_t *prog) // we need to update any RENDER_VIEWMODEL entities at this point because // csqc supplies its own view matrix CL_UpdateViewEntities(); + CL_UpdateEntityShading(); // now draw stuff! R_RenderView(); @@ -4250,7 +4256,7 @@ static void VM_CL_V_CalcRefdef(prvm_prog_t *prog) flags = PRVM_G_FLOAT(OFS_PARM1); // use the CL_GetTagMatrix function on self to ensure consistent behavior (duplicate code would be bad) - CL_GetTagMatrix(prog, &entrendermatrix, ent, 0); + CL_GetTagMatrix(prog, &entrendermatrix, ent, 0, NULL); VectorCopy(cl.csqc_viewangles, clviewangles); teleported = (flags & REFDEFFLAG_TELEPORTED) != 0; diff --git a/csprogs.c b/csprogs.c index 5f73c6ec..8d54fc0f 100644 --- a/csprogs.c +++ b/csprogs.c @@ -346,8 +346,9 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum) if (!VectorLength2(entrender->glowmod)) VectorSet(entrender->glowmod, 1, 1, 1); - // LordHavoc: use the CL_GetTagMatrix function on self to ensure consistent behavior (duplicate code would be bad) - CL_GetTagMatrix(prog, &entrender->matrix, ed, 0); + // LadyHavoc: use the CL_GetTagMatrix function on self to ensure consistent behavior (duplicate code would be bad) + // this also sets the custommodellight_origin for us + CL_GetTagMatrix(prog, &entrender->matrix, ed, 0, entrender->custommodellight_origin); // set up the animation data VM_GenerateFrameGroupBlend(prog, ed->priv.server->framegroupblend, ed); @@ -363,9 +364,9 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum) // model light if (renderflags & RF_MODELLIGHT) { - if (PRVM_clientedictvector(ed, modellight_ambient)) VectorCopy(PRVM_clientedictvector(ed, modellight_ambient), entrender->modellight_ambient); else VectorClear(entrender->modellight_ambient); - if (PRVM_clientedictvector(ed, modellight_diffuse)) VectorCopy(PRVM_clientedictvector(ed, modellight_diffuse), entrender->modellight_diffuse); else VectorClear(entrender->modellight_diffuse); - if (PRVM_clientedictvector(ed, modellight_dir)) VectorCopy(PRVM_clientedictvector(ed, modellight_dir), entrender->modellight_lightdir); else VectorClear(entrender->modellight_lightdir); + if (PRVM_clientedictvector(ed, modellight_ambient)) VectorCopy(PRVM_clientedictvector(ed, modellight_ambient), entrender->custommodellight_ambient); else VectorClear(entrender->custommodellight_ambient); + if (PRVM_clientedictvector(ed, modellight_diffuse)) VectorCopy(PRVM_clientedictvector(ed, modellight_diffuse), entrender->custommodellight_diffuse); else VectorClear(entrender->custommodellight_diffuse); + if (PRVM_clientedictvector(ed, modellight_dir)) VectorCopy(PRVM_clientedictvector(ed, modellight_dir), entrender->custommodellight_lightdir); else VectorClear(entrender->custommodellight_lightdir); entrender->flags |= RENDER_CUSTOMIZEDMODELLIGHT; } @@ -1189,15 +1190,13 @@ qboolean CL_VM_GetEntitySoundOrigin(int entnum, vec3_t out) CSQC_BEGIN; - // FIXME consider attachments here! - ed = PRVM_EDICT_NUM(entnum - MAX_EDICTS); if(!ed->priv.required->free) { mod = CL_GetModelFromEdict(ed); VectorCopy(PRVM_clientedictvector(ed, origin), out); - if(CL_GetTagMatrix(prog, &matrix, ed, 0) == 0) + if(CL_GetTagMatrix(prog, &matrix, ed, 0, NULL) == 0) Matrix4x4_OriginFromMatrix(&matrix, out); if (mod && mod->soundfromcenter) VectorMAMAM(1.0f, out, 0.5f, mod->normalmins, 0.5f, mod->normalmaxs, out); diff --git a/csprogs.h b/csprogs.h index 56761014..226cf96c 100644 --- a/csprogs.h +++ b/csprogs.h @@ -98,7 +98,7 @@ qboolean CL_VM_Parse_TempEntity(void); void CL_VM_Parse_StuffCmd(const char *msg); void CL_VM_Parse_CenterPrint(const char *msg); int CL_GetPitchSign(prvm_prog_t *prog, prvm_edict_t *ent); -int CL_GetTagMatrix(prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *ent, int tagindex); +int CL_GetTagMatrix(prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *ent, int tagindex, prvm_vec_t *shadingorigin); void CL_GetEntityMatrix(prvm_prog_t *prog, prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix); /* VMs exposing the polygon calls must call this on Init/Reset */ void VM_Polygons_Reset(prvm_prog_t *prog); diff --git a/gl_rmain.c b/gl_rmain.c index bf55c9f7..cd3d41ee 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -2213,7 +2213,7 @@ static int R_BlendFuncFlags(int src, int dst) return r; } -void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, float ambientscale, float diffusescale, float specularscale, rsurfacepass_t rsurfacepass, int texturenumsurfaces, const msurface_t **texturesurfacelist, void *surfacewaterplane, qboolean notrippy) +void R_SetupShader_Surface(const float rtlightambient[3], const float rtlightdiffuse[3], const float rtlightspecular[3], rsurfacepass_t rsurfacepass, int texturenumsurfaces, const msurface_t **texturesurfacelist, void *surfacewaterplane, qboolean notrippy) { // select a permutation of the lighting shader appropriate to this // combination of texture, entity, light source, and fogging, only use the @@ -2222,28 +2222,27 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, dpuint64 permutation = 0; unsigned int mode = 0; int blendfuncflags; - static float dummy_colormod[3] = {1, 1, 1}; - float *colormod = rsurface.colormod; + texture_t *t = rsurface.texture; float m16f[16]; matrix4x4_t tempmatrix; r_waterstate_waterplane_t *waterplane = (r_waterstate_waterplane_t *)surfacewaterplane; if (r_trippy.integer && !notrippy) permutation |= SHADERPERMUTATION_TRIPPY; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) + if (t->currentmaterialflags & MATERIALFLAG_ALPHATEST) permutation |= SHADERPERMUTATION_ALPHAKILL; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_OCCLUDE) + if (t->currentmaterialflags & MATERIALFLAG_OCCLUDE) permutation |= SHADERPERMUTATION_OCCLUDE; - if (rsurface.texture->r_water_waterscroll[0] && rsurface.texture->r_water_waterscroll[1]) + if (t->r_water_waterscroll[0] && t->r_water_waterscroll[1]) permutation |= SHADERPERMUTATION_NORMALMAPSCROLLBLEND; // todo: make generic if (rsurfacepass == RSURFPASS_BACKGROUND) { // distorted background - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERSHADER) + if (t->currentmaterialflags & MATERIALFLAG_WATERSHADER) { mode = SHADERMODE_WATER; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) + if (t->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX; - if((r_wateralpha.value < 1) && (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA)) + if((r_wateralpha.value < 1) && (t->currentmaterialflags & MATERIALFLAG_WATERALPHA)) { // this is the right thing to do for wateralpha GL_BlendFunc(GL_ONE, GL_ZERO); @@ -2256,10 +2255,10 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } } - else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFRACTION) + else if (t->currentmaterialflags & MATERIALFLAG_REFRACTION) { mode = SHADERMODE_REFRACTION; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) + if (t->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX; GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -2276,9 +2275,9 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, } else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY) { - if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f)) + if (r_glsl_offsetmapping.integer && ((R_TextureFlags(t->nmaptexture) & TEXF_ALPHA) || t->offsetbias != 0.0f)) { - switch(rsurface.texture->offsetmapping) + switch(t->offsetmapping) { case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break; case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; @@ -2286,7 +2285,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, case OFFSETMAPPING_OFF: break; } } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) + if (t->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; // normalmap (deferred prepass), may use alpha test on diffuse mode = SHADERMODE_DEFERREDGEOMETRY; @@ -2297,9 +2296,9 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, } else if (rsurfacepass == RSURFPASS_RTLIGHT) { - if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f)) + if (r_glsl_offsetmapping.integer && ((R_TextureFlags(t->nmaptexture) & TEXF_ALPHA) || t->offsetbias != 0.0f)) { - switch(rsurface.texture->offsetmapping) + switch(t->offsetmapping) { case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break; case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; @@ -2307,21 +2306,21 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, case OFFSETMAPPING_OFF: break; } } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) + if (t->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) + if (t->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX; // light source mode = SHADERMODE_LIGHTSOURCE; if (rsurface.rtlight->currentcubemap != r_texture_whitecube) permutation |= SHADERPERMUTATION_CUBEFILTER; - if (diffusescale > 0) + if (VectorLength2(rtlightdiffuse) > 0) permutation |= SHADERPERMUTATION_DIFFUSE; - if (specularscale > 0) + if (VectorLength2(rtlightspecular) > 0) permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE; if (r_refdef.fogenabled) permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE); - if (rsurface.texture->colormapping) + if (t->colormapping) permutation |= SHADERPERMUTATION_COLORMAPPING; if (r_shadow_usingshadowmap2d) { @@ -2332,69 +2331,18 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_shadow_shadowmap2ddepthbuffer) permutation |= SHADERPERMUTATION_DEPTHRGB; } - if (rsurface.texture->reflectmasktexture) + if (t->reflectmasktexture) permutation |= SHADERPERMUTATION_REFLECTCUBE; GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE); if (vid.allowalphatocoverage) GL_AlphaToCoverage(false); } - else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) - { - if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f)) - { - switch(rsurface.texture->offsetmapping) - { - case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break; - case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; - case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; - case OFFSETMAPPING_OFF: break; - } - } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) - permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) - permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX; - // unshaded geometry (fullbright or ambient model lighting) - mode = SHADERMODE_FLATCOLOR; - ambientscale = diffusescale = specularscale = 0; - if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) - permutation |= SHADERPERMUTATION_GLOW; - if (r_refdef.fogenabled) - permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE); - if (rsurface.texture->colormapping) - permutation |= SHADERPERMUTATION_COLORMAPPING; - if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)) - { - permutation |= SHADERPERMUTATION_SHADOWMAPORTHO; - permutation |= SHADERPERMUTATION_SHADOWMAP2D; - - if (r_shadow_shadowmap2ddepthbuffer) - permutation |= SHADERPERMUTATION_DEPTHRGB; - } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) - permutation |= SHADERPERMUTATION_REFLECTION; - if (rsurface.texture->reflectmasktexture) - permutation |= SHADERPERMUTATION_REFLECTCUBE; - GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); - blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); - // when using alphatocoverage, we don't need alphakill - if (vid.allowalphatocoverage) - { - if (r_transparent_alphatocoverage.integer) - { - GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); - permutation &= ~SHADERPERMUTATION_ALPHAKILL; - } - else - GL_AlphaToCoverage(false); - } - } - else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL) + else if (t->currentmaterialflags & MATERIALFLAG_MODELLIGHT) { - if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f)) + if (r_glsl_offsetmapping.integer && ((R_TextureFlags(t->nmaptexture) & TEXF_ALPHA) || t->offsetbias != 0.0f)) { - switch(rsurface.texture->offsetmapping) + switch(t->offsetmapping) { case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break; case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; @@ -2402,20 +2350,21 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, case OFFSETMAPPING_OFF: break; } } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) + if (t->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) + if (t->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX; // directional model lighting mode = SHADERMODE_LIGHTDIRECTION; - if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) + if ((t->glowtexture || t->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) permutation |= SHADERPERMUTATION_GLOW; - permutation |= SHADERPERMUTATION_DIFFUSE; - if (specularscale > 0) + if (VectorLength2(t->render_modellight_diffuse)) + permutation |= SHADERPERMUTATION_DIFFUSE; + if (VectorLength2(t->render_modellight_specular) > 0) permutation |= SHADERPERMUTATION_SPECULAR; if (r_refdef.fogenabled) permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE); - if (rsurface.texture->colormapping) + if (t->colormapping) permutation |= SHADERPERMUTATION_COLORMAPPING; if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)) { @@ -2425,11 +2374,11 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_shadow_shadowmap2ddepthbuffer) permutation |= SHADERPERMUTATION_DEPTHRGB; } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) + if (t->currentmaterialflags & MATERIALFLAG_REFLECTION) permutation |= SHADERPERMUTATION_REFLECTION; - if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)) + if (r_shadow_usingdeferredprepass && !(t->currentmaterialflags & MATERIALFLAG_BLENDED)) permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP; - if (rsurface.texture->reflectmasktexture) + if (t->reflectmasktexture) permutation |= SHADERPERMUTATION_REFLECTCUBE; if (r_shadow_bouncegrid_state.texture && cl.csqc_vidvars.drawworld) { @@ -2437,72 +2386,14 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_shadow_bouncegrid_state.directional) permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL; } - GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); - blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); + GL_BlendFunc(t->currentlayers[0].blendfunc1, t->currentlayers[0].blendfunc2); + blendfuncflags = R_BlendFuncFlags(t->currentlayers[0].blendfunc1, t->currentlayers[0].blendfunc2); // when using alphatocoverage, we don't need alphakill if (vid.allowalphatocoverage) { if (r_transparent_alphatocoverage.integer) { - GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); - permutation &= ~SHADERPERMUTATION_ALPHAKILL; - } - else - GL_AlphaToCoverage(false); - } - } - else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) - { - if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f)) - { - switch(rsurface.texture->offsetmapping) - { - case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break; - case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; - case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; - case OFFSETMAPPING_OFF: break; - } - } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) - permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) - permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX; - // ambient model lighting - mode = SHADERMODE_LIGHTDIRECTION; - if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) - permutation |= SHADERPERMUTATION_GLOW; - if (r_refdef.fogenabled) - permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE); - if (rsurface.texture->colormapping) - permutation |= SHADERPERMUTATION_COLORMAPPING; - if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)) - { - permutation |= SHADERPERMUTATION_SHADOWMAPORTHO; - permutation |= SHADERPERMUTATION_SHADOWMAP2D; - - if (r_shadow_shadowmap2ddepthbuffer) - permutation |= SHADERPERMUTATION_DEPTHRGB; - } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) - permutation |= SHADERPERMUTATION_REFLECTION; - if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)) - permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP; - if (rsurface.texture->reflectmasktexture) - permutation |= SHADERPERMUTATION_REFLECTCUBE; - if (r_shadow_bouncegrid_state.texture && cl.csqc_vidvars.drawworld) - { - permutation |= SHADERPERMUTATION_BOUNCEGRID; - if (r_shadow_bouncegrid_state.directional) - permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL; - } - GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); - blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); - // when using alphatocoverage, we don't need alphakill - if (vid.allowalphatocoverage) - { - if (r_transparent_alphatocoverage.integer) - { - GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); + GL_AlphaToCoverage((t->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); permutation &= ~SHADERPERMUTATION_ALPHAKILL; } else @@ -2511,9 +2402,9 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, } else { - if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f)) + if (r_glsl_offsetmapping.integer && ((R_TextureFlags(t->nmaptexture) & TEXF_ALPHA) || t->offsetbias != 0.0f)) { - switch(rsurface.texture->offsetmapping) + switch(t->offsetmapping) { case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break; case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; @@ -2521,16 +2412,16 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, case OFFSETMAPPING_OFF: break; } } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) + if (t->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) + if (t->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX; // lightmapped wall - if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) + if ((t->glowtexture || t->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) permutation |= SHADERPERMUTATION_GLOW; if (r_refdef.fogenabled) permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE); - if (rsurface.texture->colormapping) + if (t->colormapping) permutation |= SHADERPERMUTATION_COLORMAPPING; if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)) { @@ -2540,18 +2431,18 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_shadow_shadowmap2ddepthbuffer) permutation |= SHADERPERMUTATION_DEPTHRGB; } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) + if (t->currentmaterialflags & MATERIALFLAG_REFLECTION) permutation |= SHADERPERMUTATION_REFLECTION; - if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)) + if (r_shadow_usingdeferredprepass && !(t->currentmaterialflags & MATERIALFLAG_BLENDED)) permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP; - if (rsurface.texture->reflectmasktexture) + if (t->reflectmasktexture) permutation |= SHADERPERMUTATION_REFLECTCUBE; if (FAKELIGHT_ENABLED) { // fake lightmapping (q1bsp, q3bsp, fullbright map) mode = SHADERMODE_FAKELIGHT; permutation |= SHADERPERMUTATION_DIFFUSE; - if (specularscale > 0) + if (VectorLength2(t->render_lightmap_specular) > 0) permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE; } else if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping) @@ -2562,7 +2453,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, else mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE; permutation |= SHADERPERMUTATION_DIFFUSE; - if (specularscale > 0) + if (VectorLength2(t->render_lightmap_specular) > 0) permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE; } else if (r_glsl_deluxemapping.integer >= 2) @@ -2573,7 +2464,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, else mode = SHADERMODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR; permutation |= SHADERPERMUTATION_DIFFUSE; - if (specularscale > 0) + if (VectorLength2(t->render_lightmap_specular) > 0) permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE; } else if (rsurface.uselightmaptexture) @@ -2592,22 +2483,20 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_shadow_bouncegrid_state.directional) permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL; } - GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); - blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); + GL_BlendFunc(t->currentlayers[0].blendfunc1, t->currentlayers[0].blendfunc2); + blendfuncflags = R_BlendFuncFlags(t->currentlayers[0].blendfunc1, t->currentlayers[0].blendfunc2); // when using alphatocoverage, we don't need alphakill if (vid.allowalphatocoverage) { if (r_transparent_alphatocoverage.integer) { - GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); + GL_AlphaToCoverage((t->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); permutation &= ~SHADERPERMUTATION_ALPHAKILL; } else GL_AlphaToCoverage(false); } } - if(!(blendfuncflags & BLENDFUNC_ALLOWS_COLORMOD)) - colormod = dummy_colormod; if(!(blendfuncflags & BLENDFUNC_ALLOWS_ANYFOG)) permutation &= ~(SHADERPERMUTATION_FOGHEIGHTTEXTURE | SHADERPERMUTATION_FOGOUTSIDE | SHADERPERMUTATION_FOGINSIDE); if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACKALPHA) @@ -2629,11 +2518,11 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, { if (mode == SHADERMODE_LIGHTDIRECTION) { - hlslVSSetParameter3f(D3DVSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]); + hlslVSSetParameter3f(D3DVSREGISTER_LightDir, t->render_modellight_lightdir[0], t->render_modellight_lightdir[1], t->render_modellight_lightdir[2]); } } - Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_TexMatrix, m16f); - Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_BackgroundTexMatrix, m16f); + Matrix4x4_ToArrayFloatGL(&t->currenttexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_TexMatrix, m16f); + Matrix4x4_ToArrayFloatGL(&t->currentbackgroundtexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_BackgroundTexMatrix, m16f); Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ShadowMapMatrix, m16f); hlslVSSetParameter3f(D3DVSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]); hlslVSSetParameter4f(D3DVSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]); @@ -2641,54 +2530,52 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (mode == SHADERMODE_LIGHTSOURCE) { hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]); - hlslPSSetParameter3f(D3DPSREGISTER_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]); - hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale); - hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale); - hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale); + hlslPSSetParameter3f(D3DPSREGISTER_LightColor, 1, 1, 1); // DEPRECATED + hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, rtlightambient[0], rtlightambient[1], rtlightambient[2]); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, rtlightdiffuse[0], rtlightdiffuse[1], rtlightdiffuse[2]); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, rtlightspecular[0], rtlightspecular[1], rtlightspecular[2]); // additive passes are only darkened by fog, not tinted hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0); - hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); + hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, t->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); } else { + hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, t->render_rtlight_diffuse[0], t->render_rtlight_diffuse[1], t->render_rtlight_diffuse[2]); + hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, t->render_rtlight_specular[0], t->render_rtlight_specular[1], t->render_rtlight_specular[2]); if (mode == SHADERMODE_FLATCOLOR) { - hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0], colormod[1], colormod[2]); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, t->render_modellight_ambient[0], t->render_modellight_ambient[1], t->render_modellight_ambient[2]); } else if (mode == SHADERMODE_LIGHTDIRECTION) { - hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity) * colormod[2]); - hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]); - hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale); - hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]); - hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale); - hlslPSSetParameter3f(D3DPSREGISTER_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]); - hlslPSSetParameter3f(D3DPSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, t->render_modellight_ambient[0], t->render_modellight_ambient[1], t->render_modellight_ambient[2]); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, t->render_modellight_diffuse[0], t->render_modellight_diffuse[1], t->render_modellight_diffuse[2]); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, t->render_modellight_specular[0], t->render_modellight_specular[1], t->render_modellight_specular[2]); + hlslPSSetParameter3f(D3DPSREGISTER_LightColor, 1, 1, 1); // DEPRECATED + hlslPSSetParameter3f(D3DPSREGISTER_LightDir, t->render_modellight_lightdir[0], t->render_modellight_lightdir[1], t->render_modellight_lightdir[2]); } else { - hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]); - hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]); - hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale); - hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale); - hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, t->render_lightmap_ambient[0], t->render_lightmap_ambient[1], t->render_lightmap_ambient[2]); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, t->render_lightmap_diffuse[0], t->render_lightmap_diffuse[1], t->render_lightmap_diffuse[2]); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, t->render_lightmap_specular[0], t->render_lightmap_specular[1], t->render_lightmap_specular[2]); } // additive passes are only darkened by fog, not tinted if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0) hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0); else hlslPSSetParameter3f(D3DPSREGISTER_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]); - hlslPSSetParameter4f(D3DPSREGISTER_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor); + hlslPSSetParameter4f(D3DPSREGISTER_DistortScaleRefractReflect, r_water_refractdistort.value * t->refractfactor, r_water_refractdistort.value * t->refractfactor, r_water_reflectdistort.value * t->reflectfactor, r_water_reflectdistort.value * t->reflectfactor); hlslPSSetParameter4f(D3DPSREGISTER_ScreenScaleRefractReflect, r_fb.water.screenscale[0], r_fb.water.screenscale[1], r_fb.water.screenscale[0], r_fb.water.screenscale[1]); hlslPSSetParameter4f(D3DPSREGISTER_ScreenCenterRefractReflect, r_fb.water.screencenter[0], r_fb.water.screencenter[1], r_fb.water.screencenter[0], r_fb.water.screencenter[1]); - hlslPSSetParameter4f(D3DPSREGISTER_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]); - hlslPSSetParameter4f(D3DPSREGISTER_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]); - hlslPSSetParameter1f(D3DPSREGISTER_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin); - hlslPSSetParameter1f(D3DPSREGISTER_ReflectOffset, rsurface.texture->reflectmin); - hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (rsurface.texture->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f)); + hlslPSSetParameter4f(D3DPSREGISTER_RefractColor, t->refractcolor4f[0], t->refractcolor4f[1], t->refractcolor4f[2], t->refractcolor4f[3] * t->currentalpha); + hlslPSSetParameter4f(D3DPSREGISTER_ReflectColor, t->reflectcolor4f[0], t->reflectcolor4f[1], t->reflectcolor4f[2], t->reflectcolor4f[3] * t->currentalpha); + hlslPSSetParameter1f(D3DPSREGISTER_ReflectFactor, t->reflectmax - t->reflectmin); + hlslPSSetParameter1f(D3DPSREGISTER_ReflectOffset, t->reflectmin); + hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (t->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f)); if (mode == SHADERMODE_WATER) - hlslPSSetParameter2f(D3DPSREGISTER_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]); + hlslPSSetParameter2f(D3DPSREGISTER_NormalmapScrollBlend, t->r_water_waterscroll[0], t->r_water_waterscroll[1]); } if (permutation & SHADERPERMUTATION_SHADOWMAPORTHO) { @@ -2700,15 +2587,15 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_lightshadowmap_texturescale[0], r_shadow_lightshadowmap_texturescale[1], r_shadow_lightshadowmap_texturescale[2], r_shadow_lightshadowmap_texturescale[3]); hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_lightshadowmap_parameters[0], r_shadow_lightshadowmap_parameters[1], r_shadow_lightshadowmap_parameters[2], r_shadow_lightshadowmap_parameters[3]); } - hlslPSSetParameter3f(D3DPSREGISTER_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]); - hlslPSSetParameter1f(D3DPSREGISTER_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1)); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Glow, t->render_glowmod[0], t->render_glowmod[1], t->render_glowmod[2]); + hlslPSSetParameter1f(D3DPSREGISTER_Alpha, t->currentalpha * ((t->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? t->r_water_wateralpha : 1)); hlslPSSetParameter3f(D3DPSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]); - if (rsurface.texture->pantstexture) - hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]); + if (t->pantstexture) + hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, t->render_colormap_pants[0], t->render_colormap_pants[1], t->render_colormap_pants[2]); else hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, 0, 0, 0); - if (rsurface.texture->shirttexture) - hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]); + if (t->shirttexture) + hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, t->render_colormap_shirt[0], t->render_colormap_shirt[1], t->render_colormap_shirt[2]); else hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, 0, 0, 0); hlslPSSetParameter4f(D3DPSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]); @@ -2716,28 +2603,28 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, hlslPSSetParameter1f(D3DPSREGISTER_FogRangeRecip, rsurface.fograngerecip); hlslPSSetParameter1f(D3DPSREGISTER_FogHeightFade, rsurface.fogheightfade); hlslPSSetParameter4f(D3DPSREGISTER_OffsetMapping_ScaleSteps, - r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale, + r_glsl_offsetmapping_scale.value*t->offsetscale, max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer) ); hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality); - hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_Bias, rsurface.texture->offsetbias); + hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_Bias, t->offsetbias); hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]); hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height); - R_Mesh_TexBind(GL20TU_NORMAL , rsurface.texture->nmaptexture ); - R_Mesh_TexBind(GL20TU_COLOR , rsurface.texture->basetexture ); - R_Mesh_TexBind(GL20TU_GLOSS , rsurface.texture->glosstexture ); - R_Mesh_TexBind(GL20TU_GLOW , rsurface.texture->glowtexture ); - if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , rsurface.texture->backgroundnmaptexture ); - if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , rsurface.texture->backgroundbasetexture ); - if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , rsurface.texture->backgroundglosstexture ); - if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , rsurface.texture->backgroundglowtexture ); - if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , rsurface.texture->pantstexture ); - if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , rsurface.texture->shirttexture ); - if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , rsurface.texture->reflectmasktexture ); - if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube); + R_Mesh_TexBind(GL20TU_NORMAL , t->nmaptexture ); + R_Mesh_TexBind(GL20TU_COLOR , t->basetexture ); + R_Mesh_TexBind(GL20TU_GLOSS , t->glosstexture ); + R_Mesh_TexBind(GL20TU_GLOW , t->glowtexture ); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , t->backgroundnmaptexture ); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , t->backgroundbasetexture ); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , t->backgroundglosstexture ); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , t->backgroundglowtexture ); + if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , t->pantstexture ); + if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , t->shirttexture ); + if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , t->reflectmasktexture ); + if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , t->reflectcubetexture ? t->reflectcubetexture : r_texture_whitecube); if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE , r_texture_fogheighttexture ); if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK , r_texture_fogattenuation ); R_Mesh_TexBind(GL20TU_LIGHTMAP , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white); @@ -2806,39 +2693,39 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, { if (r_glsl_permutation->loc_ModelToLight >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToLight, 1, false, m16f);} if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3f(r_glsl_permutation->loc_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]); - if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]); - if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale); - if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale); - if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale); + if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, 1, 1, 1); // DEPRECATED + if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, rtlightambient[0], rtlightambient[1], rtlightambient[2]); + if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, rtlightdiffuse[0], rtlightdiffuse[1], rtlightdiffuse[2]); + if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, rtlightspecular[0], rtlightspecular[1], rtlightspecular[2]); // additive passes are only darkened by fog, not tinted if (r_glsl_permutation->loc_FogColor >= 0) qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0); - if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); + if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, t->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); } else { if (mode == SHADERMODE_FLATCOLOR) { - if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0], colormod[1], colormod[2]); + if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, t->render_modellight_ambient[0], t->render_modellight_ambient[1], t->render_modellight_ambient[2]); } else if (mode == SHADERMODE_LIGHTDIRECTION) { - if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[2]); - if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]); - if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale); - if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]); - if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale); - if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, rsurface.modellight_diffuse[0] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[1] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[2] * r_refdef.scene.rtlightstylevalue[0]); - if (r_glsl_permutation->loc_LightDir >= 0) qglUniform3f(r_glsl_permutation->loc_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]); + if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, t->render_modellight_ambient[0], t->render_modellight_ambient[1], t->render_modellight_ambient[2]); + if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, t->render_modellight_diffuse[0], t->render_modellight_diffuse[1], t->render_modellight_diffuse[2]); + if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, t->render_modellight_specular[0], t->render_modellight_specular[1], t->render_modellight_specular[2]); + if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, t->render_rtlight_diffuse[0], t->render_rtlight_diffuse[1], t->render_rtlight_diffuse[2]); + if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, t->render_rtlight_specular[0], t->render_rtlight_specular[1], t->render_rtlight_specular[2]); + if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, 1, 1, 1); // DEPRECATED + if (r_glsl_permutation->loc_LightDir >= 0) qglUniform3f(r_glsl_permutation->loc_LightDir, t->render_modellight_lightdir[0], t->render_modellight_lightdir[1], t->render_modellight_lightdir[2]); } else { - if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]); - if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]); - if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale); - if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale); - if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale); + if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, t->render_lightmap_ambient[0], t->render_lightmap_ambient[1], t->render_lightmap_ambient[2]); + if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, t->render_lightmap_diffuse[0], t->render_lightmap_diffuse[1], t->render_lightmap_diffuse[2]); + if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, t->render_lightmap_specular[0], t->render_lightmap_specular[1], t->render_lightmap_specular[2]); + if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, t->render_rtlight_diffuse[0], t->render_rtlight_diffuse[1], t->render_rtlight_diffuse[2]); + if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, t->render_rtlight_specular[0], t->render_rtlight_specular[1], t->render_rtlight_specular[2]); } // additive passes are only darkened by fog, not tinted if (r_glsl_permutation->loc_FogColor >= 0) @@ -2848,18 +2735,18 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, else qglUniform3f(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]); } - if (r_glsl_permutation->loc_DistortScaleRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor); + if (r_glsl_permutation->loc_DistortScaleRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_DistortScaleRefractReflect, r_water_refractdistort.value * t->refractfactor, r_water_refractdistort.value * t->refractfactor, r_water_reflectdistort.value * t->reflectfactor, r_water_reflectdistort.value * t->reflectfactor); if (r_glsl_permutation->loc_ScreenScaleRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_ScreenScaleRefractReflect, r_fb.water.screenscale[0], r_fb.water.screenscale[1], r_fb.water.screenscale[0], r_fb.water.screenscale[1]); if (r_glsl_permutation->loc_ScreenCenterRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_ScreenCenterRefractReflect, r_fb.water.screencenter[0], r_fb.water.screencenter[1], r_fb.water.screencenter[0], r_fb.water.screencenter[1]); - if (r_glsl_permutation->loc_RefractColor >= 0) qglUniform4f(r_glsl_permutation->loc_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]); - if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4f(r_glsl_permutation->loc_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]); - if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin); - if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin); - if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); - if (r_glsl_permutation->loc_NormalmapScrollBlend >= 0) qglUniform2f(r_glsl_permutation->loc_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]); - } - if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);} - if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);} + if (r_glsl_permutation->loc_RefractColor >= 0) qglUniform4f(r_glsl_permutation->loc_RefractColor, t->refractcolor4f[0], t->refractcolor4f[1], t->refractcolor4f[2], t->refractcolor4f[3] * t->currentalpha); + if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4f(r_glsl_permutation->loc_ReflectColor, t->reflectcolor4f[0], t->reflectcolor4f[1], t->reflectcolor4f[2], t->reflectcolor4f[3] * t->currentalpha); + if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectFactor, t->reflectmax - t->reflectmin); + if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectOffset, t->reflectmin); + if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, t->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); + if (r_glsl_permutation->loc_NormalmapScrollBlend >= 0) qglUniform2f(r_glsl_permutation->loc_NormalmapScrollBlend, t->r_water_waterscroll[0], t->r_water_waterscroll[1]); + } + if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&t->currenttexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);} + if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&t->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);} if (r_glsl_permutation->loc_ShadowMapMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ShadowMapMatrix, 1, false, m16f);} if (permutation & SHADERPERMUTATION_SHADOWMAPORTHO) { @@ -2872,20 +2759,20 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f(r_glsl_permutation->loc_ShadowMap_Parameters, r_shadow_lightshadowmap_parameters[0], r_shadow_lightshadowmap_parameters[1], r_shadow_lightshadowmap_parameters[2], r_shadow_lightshadowmap_parameters[3]); } - if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]); - if (r_glsl_permutation->loc_Alpha >= 0) qglUniform1f(r_glsl_permutation->loc_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1)); + if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Glow, t->render_glowmod[0], t->render_glowmod[1], t->render_glowmod[2]); + if (r_glsl_permutation->loc_Alpha >= 0) qglUniform1f(r_glsl_permutation->loc_Alpha, t->currentalpha * ((t->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? t->r_water_wateralpha : 1)); if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3f(r_glsl_permutation->loc_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]); if (r_glsl_permutation->loc_Color_Pants >= 0) { - if (rsurface.texture->pantstexture) - qglUniform3f(r_glsl_permutation->loc_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]); + if (t->pantstexture) + qglUniform3f(r_glsl_permutation->loc_Color_Pants, t->render_colormap_pants[0], t->render_colormap_pants[1], t->render_colormap_pants[2]); else qglUniform3f(r_glsl_permutation->loc_Color_Pants, 0, 0, 0); } if (r_glsl_permutation->loc_Color_Shirt >= 0) { - if (rsurface.texture->shirttexture) - qglUniform3f(r_glsl_permutation->loc_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]); + if (t->shirttexture) + qglUniform3f(r_glsl_permutation->loc_Color_Shirt, t->render_colormap_shirt[0], t->render_colormap_shirt[1], t->render_colormap_shirt[2]); else qglUniform3f(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0); } @@ -2894,13 +2781,13 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1f(r_glsl_permutation->loc_FogRangeRecip, rsurface.fograngerecip); if (r_glsl_permutation->loc_FogHeightFade >= 0) qglUniform1f(r_glsl_permutation->loc_FogHeightFade, rsurface.fogheightfade); if (r_glsl_permutation->loc_OffsetMapping_ScaleSteps >= 0) qglUniform4f(r_glsl_permutation->loc_OffsetMapping_ScaleSteps, - r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale, + r_glsl_offsetmapping_scale.value*t->offsetscale, max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer) ); if (r_glsl_permutation->loc_OffsetMapping_LodDistance >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality); - if (r_glsl_permutation->loc_OffsetMapping_Bias >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_Bias, rsurface.texture->offsetbias); + if (r_glsl_permutation->loc_OffsetMapping_Bias >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_Bias, t->offsetbias); if (r_glsl_permutation->loc_ScreenToDepth >= 0) qglUniform2f(r_glsl_permutation->loc_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]); if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height); if (r_glsl_permutation->loc_BounceGridMatrix >= 0) {Matrix4x4_Concat(&tempmatrix, &r_shadow_bouncegrid_state.matrix, &rsurface.matrix);Matrix4x4_ToArrayFloatGL(&tempmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BounceGridMatrix, 1, false, m16f);} @@ -2909,18 +2796,18 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_glsl_permutation->tex_Texture_First >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , r_texture_white ); if (r_glsl_permutation->tex_Texture_Second >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second , r_texture_white ); if (r_glsl_permutation->tex_Texture_GammaRamps >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps , r_texture_gammaramps ); - if (r_glsl_permutation->tex_Texture_Normal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Normal , rsurface.texture->nmaptexture ); - if (r_glsl_permutation->tex_Texture_Color >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Color , rsurface.texture->basetexture ); - if (r_glsl_permutation->tex_Texture_Gloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Gloss , rsurface.texture->glosstexture ); - if (r_glsl_permutation->tex_Texture_Glow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Glow , rsurface.texture->glowtexture ); - if (r_glsl_permutation->tex_Texture_SecondaryNormal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryNormal , rsurface.texture->backgroundnmaptexture ); - if (r_glsl_permutation->tex_Texture_SecondaryColor >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryColor , rsurface.texture->backgroundbasetexture ); - if (r_glsl_permutation->tex_Texture_SecondaryGloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGloss , rsurface.texture->backgroundglosstexture ); - if (r_glsl_permutation->tex_Texture_SecondaryGlow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGlow , rsurface.texture->backgroundglowtexture ); - if (r_glsl_permutation->tex_Texture_Pants >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Pants , rsurface.texture->pantstexture ); - if (r_glsl_permutation->tex_Texture_Shirt >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Shirt , rsurface.texture->shirttexture ); - if (r_glsl_permutation->tex_Texture_ReflectMask >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectMask , rsurface.texture->reflectmasktexture ); - if (r_glsl_permutation->tex_Texture_ReflectCube >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectCube , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube); + if (r_glsl_permutation->tex_Texture_Normal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Normal , t->nmaptexture ); + if (r_glsl_permutation->tex_Texture_Color >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Color , t->basetexture ); + if (r_glsl_permutation->tex_Texture_Gloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Gloss , t->glosstexture ); + if (r_glsl_permutation->tex_Texture_Glow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Glow , t->glowtexture ); + if (r_glsl_permutation->tex_Texture_SecondaryNormal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryNormal , t->backgroundnmaptexture ); + if (r_glsl_permutation->tex_Texture_SecondaryColor >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryColor , t->backgroundbasetexture ); + if (r_glsl_permutation->tex_Texture_SecondaryGloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGloss , t->backgroundglosstexture ); + if (r_glsl_permutation->tex_Texture_SecondaryGlow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGlow , t->backgroundglowtexture ); + if (r_glsl_permutation->tex_Texture_Pants >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Pants , t->pantstexture ); + if (r_glsl_permutation->tex_Texture_Shirt >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Shirt , t->shirttexture ); + if (r_glsl_permutation->tex_Texture_ReflectMask >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectMask , t->reflectmasktexture ); + if (r_glsl_permutation->tex_Texture_ReflectCube >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectCube , t->reflectcubetexture ? t->reflectcubetexture : r_texture_whitecube); if (r_glsl_permutation->tex_Texture_FogHeightTexture>= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogHeightTexture , r_texture_fogheighttexture ); if (r_glsl_permutation->tex_Texture_FogMask >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogMask , r_texture_fogattenuation ); if (r_glsl_permutation->tex_Texture_Lightmap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Lightmap , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white); @@ -2964,56 +2851,54 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, { {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelToLightM1, 1, false, m16f);} DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, 1, 1, 1); // DEPRECATED + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, rtlightambient[0], rtlightambient[1], rtlightambient[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, rtlightdiffuse[0], rtlightdiffuse[1], rtlightdiffuse[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, rtlightspecular[0], rtlightspecular[1], rtlightspecular[2]); // additive passes are only darkened by fog, not tinted DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0); - DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); + DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, t->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); } else { if (mode == SHADERMODE_FLATCOLOR) { - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0], colormod[1], colormod[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, t->render_modellight_ambient[0], t->render_modellight_ambient[1], t->render_modellight_ambient[2]); } else if (mode == SHADERMODE_LIGHTDIRECTION) { - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[2]); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale, specularscale, specularscale); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, rsurface.modellight_diffuse[0] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[1] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[2] * r_refdef.scene.rtlightstylevalue[0]); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, t->render_modellight_ambient[0], t->render_modellight_ambient[1], t->render_modellight_ambient[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, t->render_modellight_diffuse[0], t->render_modellight_diffuse[1], t->render_modellight_diffuse[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, t->render_modellight_specular[0], t->render_modellight_specular[1], t->render_modellight_specular[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, 1, 1, 1); // DEPRECATED + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightDir, t->render_modellight_lightdir[0], t->render_modellight_lightdir[1], t->render_modellight_lightdir[2]); } else { - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale, specularscale, specularscale); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, t->render_lightmap_ambient[0], t->render_lightmap_ambient[1], t->render_lightmap_ambient[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, t->render_lightmap_diffuse[0], t->render_lightmap_diffuse[1], t->render_lightmap_diffuse[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, t->render_lightmap_specular[0], t->render_lightmap_specular[1], t->render_lightmap_specular[2]); } + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, t->render_rtlight_diffuse[0], t->render_rtlight_diffuse[1], t->render_rtlight_diffuse[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, t->render_rtlight_specular[0], t->render_rtlight_specular[1], t->render_rtlight_specular[2]); // additive passes are only darkened by fog, not tinted if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0) DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0); else DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]); - DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor); + DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_DistortScaleRefractReflect, r_water_refractdistort.value * t->refractfactor, r_water_refractdistort.value * t->refractfactor, r_water_reflectdistort.value * t->reflectfactor, r_water_reflectdistort.value * t->reflectfactor); DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ScreenScaleRefractReflect, r_fb.water.screenscale[0], r_fb.water.screenscale[1], r_fb.water.screenscale[0], r_fb.water.screenscale[1]); DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ScreenCenterRefractReflect, r_fb.water.screencenter[0], r_fb.water.screencenter[1], r_fb.water.screencenter[0], r_fb.water.screencenter[1]); - DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]); - DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]); - DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin); - DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectOffset, rsurface.texture->reflectmin); - DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); - DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]); - } - {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_TexMatrixM1, 1, false, m16f);} - {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_BackgroundTexMatrixM1, 1, false, m16f);} + DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_RefractColor, t->refractcolor4f[0], t->refractcolor4f[1], t->refractcolor4f[2], t->refractcolor4f[3] * t->currentalpha); + DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ReflectColor, t->reflectcolor4f[0], t->reflectcolor4f[1], t->reflectcolor4f[2], t->reflectcolor4f[3] * t->currentalpha); + DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectFactor, t->reflectmax - t->reflectmin); + DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectOffset, t->reflectmin); + DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, t->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); + DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_NormalmapScrollBlend, t->r_water_waterscroll[0], t->r_water_waterscroll[1]); + } + {Matrix4x4_ToArrayFloatGL(&t->currenttexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_TexMatrixM1, 1, false, m16f);} + {Matrix4x4_ToArrayFloatGL(&t->currentbackgroundtexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_BackgroundTexMatrixM1, 1, false, m16f);} {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ShadowMapMatrixM1, 1, false, m16f);} if (permutation & SHADERPERMUTATION_SHADOWMAPORTHO) { @@ -3026,20 +2911,20 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ShadowMap_Parameters, r_shadow_lightshadowmap_parameters[0], r_shadow_lightshadowmap_parameters[1], r_shadow_lightshadowmap_parameters[2], r_shadow_lightshadowmap_parameters[3]); } - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]); - DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1)); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Glow, t->render_glowmod[0], t->render_glowmod[1], t->render_glowmod[2]); + DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_Alpha, t->currentalpha * ((t->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? t->r_water_wateralpha : 1)); DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]); if (DPSOFTRAST_UNIFORM_Color_Pants >= 0) { - if (rsurface.texture->pantstexture) - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]); + if (t->pantstexture) + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, t->render_colormap_pants[0], t->render_colormap_pants[1], t->render_colormap_pants[2]); else DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, 0, 0, 0); } if (DPSOFTRAST_UNIFORM_Color_Shirt >= 0) { - if (rsurface.texture->shirttexture) - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]); + if (t->shirttexture) + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, t->render_colormap_shirt[0], t->render_colormap_shirt[1], t->render_colormap_shirt[2]); else DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, 0, 0, 0); } @@ -3048,28 +2933,28 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogRangeRecip, rsurface.fograngerecip); DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogHeightFade, rsurface.fogheightfade); DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_OffsetMapping_ScaleSteps, - r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale, + r_glsl_offsetmapping_scale.value*t->offsetscale, max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer) ); DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality); - DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_Bias, rsurface.texture->offsetbias); + DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_Bias, t->offsetbias); DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]); DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height); - R_Mesh_TexBind(GL20TU_NORMAL , rsurface.texture->nmaptexture ); - R_Mesh_TexBind(GL20TU_COLOR , rsurface.texture->basetexture ); - R_Mesh_TexBind(GL20TU_GLOSS , rsurface.texture->glosstexture ); - R_Mesh_TexBind(GL20TU_GLOW , rsurface.texture->glowtexture ); - if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , rsurface.texture->backgroundnmaptexture ); - if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , rsurface.texture->backgroundbasetexture ); - if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , rsurface.texture->backgroundglosstexture ); - if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , rsurface.texture->backgroundglowtexture ); - if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , rsurface.texture->pantstexture ); - if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , rsurface.texture->shirttexture ); - if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , rsurface.texture->reflectmasktexture ); - if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube); + R_Mesh_TexBind(GL20TU_NORMAL , t->nmaptexture ); + R_Mesh_TexBind(GL20TU_COLOR , t->basetexture ); + R_Mesh_TexBind(GL20TU_GLOSS , t->glosstexture ); + R_Mesh_TexBind(GL20TU_GLOW , t->glowtexture ); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , t->backgroundnmaptexture ); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , t->backgroundbasetexture ); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , t->backgroundglosstexture ); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , t->backgroundglowtexture ); + if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , t->pantstexture ); + if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , t->shirttexture ); + if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , t->reflectmasktexture ); + if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , t->reflectcubetexture ? t->reflectcubetexture : r_texture_whitecube); if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE , r_texture_fogheighttexture ); if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK , r_texture_fogattenuation ); R_Mesh_TexBind(GL20TU_LIGHTMAP , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white); @@ -5123,171 +5008,6 @@ void R_AnimCache_CacheVisibleEntities(void) //================================================================================== -extern cvar_t r_overheadsprites_pushback; - -static void R_GetDirectedFullbright(vec3_t ambient, vec3_t diffuse, vec3_t worldspacenormal) -{ - vec3_t angles; - - VectorSet(ambient, r_fullbright_directed_ambient.value, r_fullbright_directed_ambient.value, r_fullbright_directed_ambient.value); - VectorSet(diffuse, r_fullbright_directed_diffuse.value, r_fullbright_directed_diffuse.value, r_fullbright_directed_diffuse.value); - - // Use cl.viewangles and not r_refdef.view.forward here so it is the - // same for all stereo views, and to better handle pitches outside - // [-90, 90] (in_pitch_* cvars allow that). - VectorCopy(cl.viewangles, angles); - if (r_fullbright_directed_pitch_relative.integer) { - angles[PITCH] += r_fullbright_directed_pitch.value; - } else { - angles[PITCH] = r_fullbright_directed_pitch.value; - } - AngleVectors(angles, worldspacenormal, NULL, NULL); - VectorNegate(worldspacenormal, worldspacenormal); -} - -static void R_View_UpdateEntityLighting (void) -{ - int i; - entity_render_t *ent; - vec3_t tempdiffusenormal, avg; - vec_t f, fa, fd, fdd; - qboolean skipunseen = r_shadows.integer != 1; //|| R_Shadow_ShadowMappingEnabled(); - - for (i = 0;i < r_refdef.scene.numentities;i++) - { - ent = r_refdef.scene.entities[i]; - - // skip unseen models - if ((!r_refdef.viewcache.entityvisible[i] && skipunseen)) - continue; - - // skip bsp models - if (ent->model && ent->model == cl.worldmodel) - { - // TODO: use modellight for r_ambient settings on world? - // The logic here currently matches RSurf_ActiveWorldEntity. - if (r_fullbright_directed.integer && (r_fullbright.integer || !ent->model || !ent->model->lit)) - { - R_GetDirectedFullbright(ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal); - Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir); - if(VectorLength2(ent->modellight_lightdir) == 0) - VectorSet(ent->modellight_lightdir, 0, 0, 1); // have to set SOME valid vector here - VectorNormalize(ent->modellight_lightdir); - } - else - { - VectorSet(ent->modellight_ambient, 0, 0, 0); - VectorSet(ent->modellight_diffuse, 0, 0, 0); - VectorSet(ent->modellight_lightdir, 0, 0, 1); - } - continue; - } - - if (ent->flags & RENDER_CUSTOMIZEDMODELLIGHT) - { - // aleady updated by CSQC - // TODO: force modellight on BSP models in this case? - VectorCopy(ent->modellight_lightdir, tempdiffusenormal); - } - else - { - // fetch the lighting from the worldmodel data - VectorClear(ent->modellight_ambient); - VectorClear(ent->modellight_diffuse); - VectorClear(tempdiffusenormal); - if (ent->flags & RENDER_LIGHT) - { - vec3_t org; - Matrix4x4_OriginFromMatrix(&ent->matrix, org); - - // complete lightning for lit sprites - // todo: make a EF_ field so small ents could be lit purely by modellight and skipping real rtlight pass (like EF_NORTLIGHT)? - if (ent->model->type == mod_sprite && !(ent->model->data_textures[0].basematerialflags & MATERIALFLAG_FULLBRIGHT)) - { - if (ent->model->sprite.sprnum_type == SPR_OVERHEAD) // apply offset for overhead sprites - org[2] = org[2] + r_overheadsprites_pushback.value; - R_LightPoint(ent->modellight_ambient, org, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT); - } - else if (!r_fullbright.integer && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->lit && r_refdef.scene.worldmodel->brush.LightPoint) - { - R_CompleteLightPoint(ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal, org, LP_LIGHTMAP); - } - else if (r_fullbright_directed.integer) - { - R_GetDirectedFullbright(ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal); - } - else - { - VectorSet(ent->modellight_ambient, 1, 1, 1); - } - - if(ent->flags & RENDER_EQUALIZE) - { - // first fix up ambient lighting... - if(r_equalize_entities_minambient.value > 0) - { - fd = 0.299f * ent->modellight_diffuse[0] + 0.587f * ent->modellight_diffuse[1] + 0.114f * ent->modellight_diffuse[2]; - if(fd > 0) - { - fa = (0.299f * ent->modellight_ambient[0] + 0.587f * ent->modellight_ambient[1] + 0.114f * ent->modellight_ambient[2]); - if(fa < r_equalize_entities_minambient.value * fd) - { - // solve: - // fa'/fd' = minambient - // fa'+0.25*fd' = fa+0.25*fd - // ... - // fa' = fd' * minambient - // fd'*(0.25+minambient) = fa+0.25*fd - // ... - // fd' = (fa+0.25*fd) * 1 / (0.25+minambient) - // fa' = (fa+0.25*fd) * minambient / (0.25+minambient) - // ... - fdd = (fa + 0.25f * fd) / (0.25f + r_equalize_entities_minambient.value); - f = fdd / fd; // f>0 because all this is additive; f<1 because fddmodellight_ambient, (1-f)*0.25f, ent->modellight_diffuse, ent->modellight_ambient); - VectorScale(ent->modellight_diffuse, f, ent->modellight_diffuse); - } - } - } - - if(r_equalize_entities_to.value > 0 && r_equalize_entities_by.value != 0) - { - fa = 0.299f * ent->modellight_ambient[0] + 0.587f * ent->modellight_ambient[1] + 0.114f * ent->modellight_ambient[2]; - fd = 0.299f * ent->modellight_diffuse[0] + 0.587f * ent->modellight_diffuse[1] + 0.114f * ent->modellight_diffuse[2]; - f = fa + 0.25 * fd; - if(f > 0) - { - // adjust brightness and saturation to target - avg[0] = avg[1] = avg[2] = fa / f; - VectorLerp(ent->modellight_ambient, r_equalize_entities_by.value, avg, ent->modellight_ambient); - avg[0] = avg[1] = avg[2] = fd / f; - VectorLerp(ent->modellight_diffuse, r_equalize_entities_by.value, avg, ent->modellight_diffuse); - } - } - } - } - else - { - // EF_FULLBRIGHT entity. - if (r_fullbright_directed.integer) - { - R_GetDirectedFullbright(ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal); - } - else - { - VectorSet(ent->modellight_ambient, 1, 1, 1); - } - } - } - - // move the light direction into modelspace coordinates for lighting code - Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir); - if(VectorLength2(ent->modellight_lightdir) == 0) - VectorSet(ent->modellight_lightdir, 0, 0, 1); // have to set SOME valid vector here - VectorNormalize(ent->modellight_lightdir); - } -} - qboolean R_CanSeeBox(int numsamples, vec_t eyejitter, vec_t entboxenlarge, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs) { int i; @@ -5554,7 +5274,7 @@ void R_HDR_UpdateIrisAdaptation(const vec3_t point) p[0] = point[0] + irisvecs[c][0] * r_hdr_irisadaptation_radius.value; p[1] = point[1] + irisvecs[c][1] * r_hdr_irisadaptation_radius.value; p[2] = point[2] + irisvecs[c][2] * r_hdr_irisadaptation_radius.value; - R_CompleteLightPoint(ambient, diffuse, diffusenormal, p, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT); + R_CompleteLightPoint(ambient, diffuse, diffusenormal, p, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT, r_refdef.scene.lightmapintensity, r_refdef.scene.ambientintensity); d = DotProduct(forward, diffusenormal); brightness += VectorLength(ambient); if (d > 0) @@ -5785,7 +5505,6 @@ static void R_View_UpdateWithScissor(const int *myscissor) R_View_SetFrustum(myscissor); R_View_WorldVisibility(r_refdef.view.useclipplane); R_View_UpdateEntityVisible(); - R_View_UpdateEntityLighting(); } static void R_View_Update(void) @@ -5794,7 +5513,6 @@ static void R_View_Update(void) R_View_SetFrustum(NULL); R_View_WorldVisibility(r_refdef.view.useclipplane); R_View_UpdateEntityVisible(); - R_View_UpdateEntityLighting(); } float viewscalefpsadjusted = 1.0f; @@ -7202,7 +6920,7 @@ void R_UpdateVariables(void) { R_Textures_Frame(); - r_refdef.scene.ambient = r_ambient.value * (1.0f / 64.0f); + r_refdef.scene.ambientintensity = r_ambient.value * (1.0f / 64.0f); r_refdef.farclip = r_farclip_base.value; if (r_refdef.scene.worldmodel) @@ -7220,14 +6938,14 @@ void R_UpdateVariables(void) r_refdef.scene.rtworldshadows = r_shadow_realtime_world_shadows.integer && vid.stencil; r_refdef.scene.rtdlight = r_shadow_realtime_dlight.integer != 0 && !gl_flashblend.integer && r_dynamic.integer; r_refdef.scene.rtdlightshadows = r_refdef.scene.rtdlight && r_shadow_realtime_dlight_shadows.integer && vid.stencil; - r_refdef.lightmapintensity = r_refdef.scene.rtworld ? r_shadow_realtime_world_lightmaps.value : 1; + r_refdef.scene.lightmapintensity = r_refdef.scene.rtworld ? r_shadow_realtime_world_lightmaps.value : 1; if (FAKELIGHT_ENABLED) { - r_refdef.lightmapintensity *= r_fakelight_intensity.value; + r_refdef.scene.lightmapintensity *= r_fakelight_intensity.value; } else if (r_refdef.scene.worldmodel) { - r_refdef.lightmapintensity *= r_refdef.scene.worldmodel->lightmapscale; + r_refdef.scene.lightmapintensity *= r_refdef.scene.worldmodel->lightmapscale; } if (r_showsurfaces.integer) { @@ -7235,7 +6953,7 @@ void R_UpdateVariables(void) r_refdef.scene.rtworldshadows = false; r_refdef.scene.rtdlight = false; r_refdef.scene.rtdlightshadows = false; - r_refdef.lightmapintensity = 0; + r_refdef.scene.lightmapintensity = 0; } r_gpuskeletal = false; @@ -7372,7 +7090,7 @@ void R_RenderView(void) if (r_timereport_active) R_TimeReport("start"); r_textureframe++; // used only by R_GetCurrentTexture - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity + rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity if(R_CompileShader_CheckStaticParms()) R_GLSL_Restart_f(); @@ -7622,7 +7340,7 @@ void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) if (r_refdef.scene.extraupdate) S_ExtraUpdate (); - if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && !r_shadows_drawafterrtlighting.integer && r_refdef.lightmapintensity > 0) + if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && !r_shadows_drawafterrtlighting.integer && r_refdef.scene.lightmapintensity > 0) { R_ResetViewRendering3D(fbo, depthtexture, colortexture); R_Shadow_DrawModelShadows(); @@ -7643,7 +7361,7 @@ void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) if (r_refdef.scene.extraupdate) S_ExtraUpdate (); - if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && r_shadows_drawafterrtlighting.integer && r_refdef.lightmapintensity > 0) + if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && r_shadows_drawafterrtlighting.integer && r_refdef.scene.lightmapintensity > 0) { R_ResetViewRendering3D(fbo, depthtexture, colortexture); R_Shadow_DrawModelShadows(); @@ -7801,7 +7519,7 @@ static void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float c int i, edge; float *v, *c, f1, f2, edgemins[3], edgemaxs[3]; - RSurf_ActiveWorldEntity(); + RSurf_ActiveModelEntity(r_refdef.scene.worldentity, false, false, false); GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GL_DepthMask(false); @@ -7962,7 +7680,7 @@ static void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); GL_DepthMask(false); } - else if (rsurface.colormod[3] < 1) + else if (ent->alpha < 1) { GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GL_DepthMask(false); @@ -7979,10 +7697,10 @@ static void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const memcpy(color4f, nomodelcolor4f, sizeof(float[6*4])); for (i = 0, c = color4f;i < 6;i++, c += 4) { - c[0] *= rsurface.colormod[0]; - c[1] *= rsurface.colormod[1]; - c[2] *= rsurface.colormod[2]; - c[3] *= rsurface.colormod[3]; + c[0] *= ent->render_fullbright[0] * r_refdef.view.colorscale; + c[1] *= ent->render_fullbright[1] * r_refdef.view.colorscale; + c[2] *= ent->render_fullbright[2] * r_refdef.view.colorscale; + c[3] *= ent->alpha; } if (r_refdef.fogenabled) { @@ -8325,10 +8043,11 @@ static void R_LoadQWSkin(r_qwskincache_t *cache, const char *skinname) texture_t *R_GetCurrentTexture(texture_t *t) { - int i; + int i, q; const entity_render_t *ent = rsurface.entity; dp_model_t *model = ent->model; // when calling this, ent must not be NULL q3shaderinfo_layer_tcmod_t *tcmod; + float specularscale = 0.0f; if (t->update_lastrenderframe == r_textureframe && t->update_lastrenderentity == (void *)ent && !rsurface.forcecurrenttextureupdate) return t->currentframe; @@ -8392,27 +8111,115 @@ texture_t *R_GetCurrentTexture(texture_t *t) t->backgroundcurrentskinframe = t->backgroundshaderpass->skinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->backgroundshaderpass->framerate, t->backgroundshaderpass->numframes)]; t->currentmaterialflags = t->basematerialflags; - t->currentalpha = rsurface.colormod[3] * t->basealpha; + t->currentalpha = rsurface.entity->alpha * t->basealpha; if (t->basematerialflags & MATERIALFLAG_WATERALPHA && (model->brush.supportwateralpha || r_novis.integer || r_trippy.integer)) t->currentalpha *= r_wateralpha.value; if(t->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW; // we apply wateralpha later if(!r_fb.water.enabled || r_refdef.view.isoverlay) t->currentmaterialflags &= ~(MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA); - if (!(rsurface.ent_flags & RENDER_LIGHT)) - t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT; + + // decide on which type of lighting to use for this surface + if (rsurface.entity->render_modellight_forced) + t->currentmaterialflags |= MATERIALFLAG_MODELLIGHT; + if (rsurface.entity->render_rtlight_disabled) + t->currentmaterialflags |= MATERIALFLAG_NORTLIGHT; + if (t->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND && !(R_BlendFuncFlags(t->customblendfunc[0], t->customblendfunc[1]) & BLENDFUNC_ALLOWS_COLORMOD)) + { + // some CUSTOMBLEND blendfuncs are too weird for anything but fullbright rendering, and even then we have to ignore colormod and view colorscale + t->currentmaterialflags = t->currentmaterialflags | MATERIALFLAG_MODELLIGHT | MATERIALFLAG_NORTLIGHT; + for (q = 0; q < 3; q++) + { + t->render_glowmod[q] = rsurface.entity->glowmod[q]; + t->render_modellight_lightdir[q] = q == 2; + t->render_modellight_ambient[q] = 1; + t->render_modellight_diffuse[q] = 0; + t->render_modellight_specular[q] = 0; + t->render_lightmap_ambient[q] = 0; + t->render_lightmap_diffuse[q] = 0; + t->render_lightmap_specular[q] = 0; + t->render_rtlight_diffuse[q] = 0; + t->render_rtlight_specular[q] = 0; + } + } + else if ((t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) || !(rsurface.ent_flags & RENDER_LIGHT)) + { + // fullbright is basically MATERIALFLAG_MODELLIGHT but with ambient locked to 1,1,1 and no shading + t->currentmaterialflags = t->currentmaterialflags | MATERIALFLAG_NORTLIGHT | MATERIALFLAG_MODELLIGHT; + for (q = 0; q < 3; q++) + { + t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale; + t->render_modellight_ambient[q] = rsurface.entity->render_fullbright[q] * r_refdef.view.colorscale; + t->render_modellight_lightdir[q] = q == 2; + t->render_modellight_diffuse[q] = 0; + t->render_modellight_specular[q] = 0; + t->render_lightmap_ambient[q] = 0; + t->render_lightmap_diffuse[q] = 0; + t->render_lightmap_specular[q] = 0; + t->render_rtlight_diffuse[q] = 0; + t->render_rtlight_specular[q] = 0; + } + } else if (FAKELIGHT_ENABLED) { // no modellight if using fakelight for the map + t->currentmaterialflags = (t->currentmaterialflags | MATERIALFLAG_NORTLIGHT) & ~(MATERIALFLAG_MODELLIGHT); + for (q = 0; q < 3; q++) + { + t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale; + t->render_modellight_lightdir[q] = rsurface.entity->render_modellight_lightdir[q]; + t->render_modellight_ambient[q] = rsurface.entity->render_modellight_ambient[q] * r_refdef.view.colorscale; + t->render_modellight_diffuse[q] = rsurface.entity->render_modellight_diffuse[q] * r_refdef.view.colorscale; + t->render_modellight_specular[q] = rsurface.entity->render_modellight_specular[q] * r_refdef.view.colorscale; + t->render_lightmap_ambient[q] = 0; + t->render_lightmap_diffuse[q] = 0; + t->render_lightmap_specular[q] = 0; + t->render_rtlight_diffuse[q] = 0; + t->render_rtlight_specular[q] = 0; + } + } + else if ((rsurface.ent_flags & (RENDER_DYNAMICMODELLIGHT | RENDER_CUSTOMIZEDMODELLIGHT)) || rsurface.modeltexcoordlightmap2f == NULL) + { + // ambient + single direction light (modellight) + t->currentmaterialflags |= MATERIALFLAG_MODELLIGHT; + for (q = 0; q < 3; q++) + { + t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale; + t->render_modellight_lightdir[q] = rsurface.entity->render_modellight_lightdir[q]; + t->render_modellight_ambient[q] = rsurface.entity->render_modellight_ambient[q] * r_refdef.view.colorscale; + t->render_modellight_diffuse[q] = rsurface.entity->render_modellight_diffuse[q] * r_refdef.view.colorscale; + t->render_modellight_specular[q] = rsurface.entity->render_modellight_specular[q] * r_refdef.view.colorscale; + t->render_lightmap_ambient[q] = 0; + t->render_lightmap_diffuse[q] = 0; + t->render_lightmap_specular[q] = 0; + t->render_rtlight_diffuse[q] = rsurface.entity->render_rtlight_diffuse[q] * r_refdef.view.colorscale; + t->render_rtlight_specular[q] = rsurface.entity->render_rtlight_specular[q] * r_refdef.view.colorscale; + } } - else if ((rsurface.modeltexcoordlightmap2f == NULL || (rsurface.ent_flags & (RENDER_DYNAMICMODELLIGHT | RENDER_CUSTOMIZEDMODELLIGHT))) && !(t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) + else { - // pick a model lighting mode - if (VectorLength2(rsurface.modellight_diffuse) >= (1.0f / 256.0f)) - t->currentmaterialflags |= MATERIALFLAG_MODELLIGHT | MATERIALFLAG_MODELLIGHT_DIRECTIONAL; - else - t->currentmaterialflags |= MATERIALFLAG_MODELLIGHT; + // lightmap - 2x diffuse and specular brightness because bsp files have 0-2 colors as 0-1 + for (q = 0; q < 3; q++) + { + t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale; + t->render_modellight_lightdir[q] = rsurface.entity->render_modellight_lightdir[q] * r_refdef.view.colorscale; + t->render_modellight_ambient[q] = rsurface.entity->render_modellight_ambient[q] * r_refdef.view.colorscale; + t->render_modellight_diffuse[q] = 0; + t->render_modellight_specular[q] = 0; + t->render_lightmap_ambient[q] = rsurface.entity->render_lightmap_ambient[q] * r_refdef.view.colorscale; + t->render_lightmap_diffuse[q] = rsurface.entity->render_lightmap_diffuse[q] * 2 * r_refdef.view.colorscale; + t->render_lightmap_specular[q] = rsurface.entity->render_lightmap_specular[q] * 2 * r_refdef.view.colorscale; + t->render_rtlight_diffuse[q] = rsurface.entity->render_rtlight_diffuse[q] * r_refdef.view.colorscale; + t->render_rtlight_specular[q] = rsurface.entity->render_rtlight_specular[q] * r_refdef.view.colorscale; + } + } + + for (q = 0; q < 3; q++) + { + t->render_colormap_pants[q] = rsurface.entity->colormap_pantscolor[q]; + t->render_colormap_shirt[q] = rsurface.entity->colormap_shirtcolor[q]; } + if (rsurface.ent_flags & RENDER_ADDITIVE) t->currentmaterialflags |= MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW; else if (t->currentalpha < 1) @@ -8457,7 +8264,7 @@ texture_t *R_GetCurrentTexture(texture_t *t) for (i = 0, tcmod = t->materialshaderpass->tcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++) R_tcMod_ApplyToMatrix(&t->currenttexmatrix, tcmod, t->currentmaterialflags); - t->colormapping = VectorLength2(rsurface.colormap_pantscolor) + VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f); + t->colormapping = VectorLength2(t->render_colormap_pants) + VectorLength2(t->render_colormap_shirt) >= (1.0f / 1048576.0f); if (t->currentskinframe->qpixels) R_SkinFrame_GenerateTexturesFromQPixels(t->currentskinframe, t->colormapping); t->basetexture = (!t->colormapping && t->currentskinframe->merged) ? t->currentskinframe->merged : t->currentskinframe->base; @@ -8497,7 +8304,6 @@ texture_t *R_GetCurrentTexture(texture_t *t) } t->specularpower = r_shadow_glossexponent.value; // TODO: store reference values for these in the texture? - t->specularscale = 0; if (r_shadow_gloss.integer > 0) { if (t->currentskinframe->gloss || (t->backgroundcurrentskinframe && t->backgroundcurrentskinframe->gloss)) @@ -8506,20 +8312,19 @@ texture_t *R_GetCurrentTexture(texture_t *t) { t->glosstexture = t->currentskinframe->gloss ? t->currentskinframe->gloss : r_texture_white; t->backgroundglosstexture = (t->backgroundcurrentskinframe && t->backgroundcurrentskinframe->gloss) ? t->backgroundcurrentskinframe->gloss : r_texture_white; - t->specularscale = r_shadow_glossintensity.value; + specularscale = r_shadow_glossintensity.value; } } else if (r_shadow_gloss.integer >= 2 && r_shadow_gloss2intensity.value > 0) { t->glosstexture = r_texture_white; t->backgroundglosstexture = r_texture_white; - t->specularscale = r_shadow_gloss2intensity.value; + specularscale = r_shadow_gloss2intensity.value; t->specularpower = r_shadow_gloss2exponent.value; } } - t->specularscale *= t->specularscalemod; + specularscale *= t->specularscalemod; t->specularpower *= t->specularpowermod; - t->rtlightambient = 0; // lightmaps mode looks bad with dlights using actual texturing, so turn // off the colormap and glossmap, but leave the normalmap on as it still @@ -8540,12 +8345,20 @@ texture_t *R_GetCurrentTexture(texture_t *t) t->backgroundnmaptexture = r_texture_blanknormalmap; t->backgroundglosstexture = r_texture_black; t->backgroundglowtexture = NULL; - t->specularscale = 0; - t->currentmaterialflags = MATERIALFLAG_WALL | (t->currentmaterialflags & (MATERIALFLAG_NOCULLFACE | MATERIALFLAG_MODELLIGHT | MATERIALFLAG_MODELLIGHT_DIRECTIONAL | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SHORTDEPTHRANGE)); + specularscale = 0; + t->currentmaterialflags = MATERIALFLAG_WALL | (t->currentmaterialflags & (MATERIALFLAG_NOCULLFACE | MATERIALFLAG_MODELLIGHT | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SHORTDEPTHRANGE)); + } + + if (specularscale != 1.0f) + { + for (q = 0; q < 3; q++) + { + t->render_modellight_specular[q] *= specularscale; + t->render_lightmap_specular[q] *= specularscale; + t->render_rtlight_specular[q] *= specularscale; + } } - Vector4Set(t->lightmapcolor, rsurface.colormod[0], rsurface.colormod[1], rsurface.colormod[2], t->currentalpha); - VectorClear(t->dlightcolor); t->currentnumlayers = 0; if (t->currentmaterialflags & MATERIALFLAG_WALL) { @@ -8571,54 +8384,38 @@ texture_t *R_GetCurrentTexture(texture_t *t) blendfunc1 = GL_ONE; blendfunc2 = GL_ZERO; } - // don't colormod evilblend textures - if(!(R_BlendFuncFlags(blendfunc1, blendfunc2) & BLENDFUNC_ALLOWS_COLORMOD)) - VectorSet(t->lightmapcolor, 1, 1, 1); depthmask = !(t->currentmaterialflags & MATERIALFLAG_BLENDED); - if (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) + if (t->currentmaterialflags & MATERIALFLAG_MODELLIGHT) { - // fullbright is not affected by r_refdef.lightmapintensity - R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_TEXTURE, t->basetexture, &t->currenttexmatrix, t->lightmapcolor[0], t->lightmapcolor[1], t->lightmapcolor[2], t->lightmapcolor[3]); - if (VectorLength2(rsurface.colormap_pantscolor) >= (1.0f / 1048576.0f) && t->pantstexture) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->pantstexture, &t->currenttexmatrix, rsurface.colormap_pantscolor[0] * t->lightmapcolor[0], rsurface.colormap_pantscolor[1] * t->lightmapcolor[1], rsurface.colormap_pantscolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]); - if (VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->shirttexture) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->shirttexture, &t->currenttexmatrix, rsurface.colormap_shirtcolor[0] * t->lightmapcolor[0], rsurface.colormap_shirtcolor[1] * t->lightmapcolor[1], rsurface.colormap_shirtcolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]); + // basic lit geometry + R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE, t->basetexture, &t->currenttexmatrix, t->render_lightmap_diffuse[0], t->render_lightmap_diffuse[1], t->render_lightmap_diffuse[2], t->currentalpha); + // add pants/shirt if needed + if (VectorLength2(t->render_colormap_pants) >= (1.0f / 1048576.0f) && t->pantstexture) + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->pantstexture, &t->currenttexmatrix, t->render_colormap_pants[0] * t->render_lightmap_diffuse[0], t->render_colormap_pants[1] * t->render_lightmap_diffuse[1], t->render_colormap_pants[2] * t->render_lightmap_diffuse[2], t->currentalpha); + if (VectorLength2(t->render_colormap_shirt) >= (1.0f / 1048576.0f) && t->shirttexture) + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->shirttexture, &t->currenttexmatrix, t->render_colormap_shirt[0] * t->render_lightmap_diffuse[0], t->render_colormap_shirt[1] * t->render_lightmap_diffuse[1], t->render_colormap_shirt[2] * t->render_lightmap_diffuse[2], t->currentalpha); } else { - vec3_t ambientcolor; - float colorscale; - // set the color tint used for lights affecting this surface - VectorSet(t->dlightcolor, t->lightmapcolor[0] * t->lightmapcolor[3], t->lightmapcolor[1] * t->lightmapcolor[3], t->lightmapcolor[2] * t->lightmapcolor[3]); - colorscale = 2; - // q3bsp has no lightmap updates, so the lightstylevalue that - // would normally be baked into the lightmap must be - // applied to the color - // FIXME: r_glsl 1 rendering doesn't support overbright lightstyles with this (the default light style is not overbright) - if (model->type == mod_brushq3) - colorscale *= r_refdef.scene.rtlightstylevalue[0]; - colorscale *= r_refdef.lightmapintensity; - VectorScale(t->lightmapcolor, r_refdef.scene.ambient, ambientcolor); - VectorScale(t->lightmapcolor, colorscale, t->lightmapcolor); // basic lit geometry - R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE, t->basetexture, &t->currenttexmatrix, t->lightmapcolor[0], t->lightmapcolor[1], t->lightmapcolor[2], t->lightmapcolor[3]); + R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE, t->basetexture, &t->currenttexmatrix, t->render_lightmap_diffuse[0], t->render_lightmap_diffuse[1], t->render_lightmap_diffuse[2], t->currentalpha); // add pants/shirt if needed - if (VectorLength2(rsurface.colormap_pantscolor) >= (1.0f / 1048576.0f) && t->pantstexture) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->pantstexture, &t->currenttexmatrix, rsurface.colormap_pantscolor[0] * t->lightmapcolor[0], rsurface.colormap_pantscolor[1] * t->lightmapcolor[1], rsurface.colormap_pantscolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]); - if (VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->shirttexture) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->shirttexture, &t->currenttexmatrix, rsurface.colormap_shirtcolor[0] * t->lightmapcolor[0], rsurface.colormap_shirtcolor[1] * t->lightmapcolor[1], rsurface.colormap_shirtcolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]); + if (VectorLength2(t->render_colormap_pants) >= (1.0f / 1048576.0f) && t->pantstexture) + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->pantstexture, &t->currenttexmatrix, t->render_colormap_pants[0] * t->render_lightmap_diffuse[0], t->render_colormap_pants[1] * t->render_lightmap_diffuse[1], t->render_colormap_pants[2] * t->render_lightmap_diffuse[2], t->currentalpha); + if (VectorLength2(t->render_colormap_shirt) >= (1.0f / 1048576.0f) && t->shirttexture) + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->shirttexture, &t->currenttexmatrix, t->render_colormap_shirt[0] * t->render_lightmap_diffuse[0], t->render_colormap_shirt[1] * t->render_lightmap_diffuse[1], t->render_colormap_shirt[2] * t->render_lightmap_diffuse[2], t->currentalpha); // now add ambient passes if needed - if (VectorLength2(ambientcolor) >= (1.0f/1048576.0f)) + if (VectorLength2(t->render_lightmap_ambient) >= (1.0f/1048576.0f)) { - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->basetexture, &t->currenttexmatrix, ambientcolor[0], ambientcolor[1], ambientcolor[2], t->lightmapcolor[3]); - if (VectorLength2(rsurface.colormap_pantscolor) >= (1.0f / 1048576.0f) && t->pantstexture) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->pantstexture, &t->currenttexmatrix, rsurface.colormap_pantscolor[0] * ambientcolor[0], rsurface.colormap_pantscolor[1] * ambientcolor[1], rsurface.colormap_pantscolor[2] * ambientcolor[2], t->lightmapcolor[3]); - if (VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->shirttexture) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->shirttexture, &t->currenttexmatrix, rsurface.colormap_shirtcolor[0] * ambientcolor[0], rsurface.colormap_shirtcolor[1] * ambientcolor[1], rsurface.colormap_shirtcolor[2] * ambientcolor[2], t->lightmapcolor[3]); + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->basetexture, &t->currenttexmatrix, t->render_lightmap_ambient[0], t->render_lightmap_ambient[1], t->render_lightmap_ambient[2], t->currentalpha); + if (VectorLength2(t->render_colormap_pants) >= (1.0f / 1048576.0f) && t->pantstexture) + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->pantstexture, &t->currenttexmatrix, t->render_colormap_pants[0] * t->render_lightmap_ambient[0], t->render_colormap_pants[1] * t->render_lightmap_ambient[1], t->render_colormap_pants[2] * t->render_lightmap_ambient[2], t->currentalpha); + if (VectorLength2(t->render_colormap_shirt) >= (1.0f / 1048576.0f) && t->shirttexture) + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->shirttexture, &t->currenttexmatrix, t->render_colormap_shirt[0] * t->render_lightmap_ambient[0], t->render_colormap_shirt[1] * t->render_lightmap_ambient[1], t->render_colormap_shirt[2] * t->render_lightmap_ambient[2], t->currentalpha); } } if (t->glowtexture != NULL && !gl_lightmaps.integer) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->glowtexture, &t->currenttexmatrix, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2], t->lightmapcolor[3]); + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->glowtexture, &t->currenttexmatrix, t->render_glowmod[0], t->render_glowmod[1], t->render_glowmod[2], t->currentalpha); if (r_refdef.fogenabled && !(t->currentmaterialflags & MATERIALFLAG_ADD)) { // if this is opaque use alpha blend which will darken the earlier @@ -8632,7 +8429,7 @@ texture_t *R_GetCurrentTexture(texture_t *t) // were darkened by fog already, and we should not add fog color // (because the background was not darkened, there is no fog color // that was lost behind it). - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_BLENDED) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->fogtexture, &t->currenttexmatrix, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2], t->lightmapcolor[3]); + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_BLENDED) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->fogtexture, &t->currenttexmatrix, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2], t->currentalpha); } } @@ -8641,143 +8438,6 @@ texture_t *R_GetCurrentTexture(texture_t *t) rsurfacestate_t rsurface; -void RSurf_ActiveWorldEntity(void) -{ - dp_model_t *model = r_refdef.scene.worldmodel; - //if (rsurface.entity == r_refdef.scene.worldentity) - // return; - rsurface.entity = r_refdef.scene.worldentity; - rsurface.skeleton = NULL; - memset(rsurface.userwavefunc_param, 0, sizeof(rsurface.userwavefunc_param)); - rsurface.ent_skinnum = 0; - rsurface.ent_qwskin = -1; - rsurface.ent_flags = r_refdef.scene.worldentity->flags; - rsurface.shadertime = r_refdef.scene.time; - rsurface.matrix = identitymatrix; - rsurface.inversematrix = identitymatrix; - rsurface.matrixscale = 1; - rsurface.inversematrixscale = 1; - R_EntityMatrix(&identitymatrix); - VectorCopy(r_refdef.view.origin, rsurface.localvieworigin); - Vector4Copy(r_refdef.fogplane, rsurface.fogplane); - rsurface.fograngerecip = r_refdef.fograngerecip; - rsurface.fogheightfade = r_refdef.fogheightfade; - rsurface.fogplaneviewdist = r_refdef.fogplaneviewdist; - rsurface.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * rsurface.fograngerecip; - if (r_fullbright_directed.integer && (r_fullbright.integer || !model->lit)) - { - R_GetDirectedFullbright(rsurface.modellight_ambient, rsurface.modellight_diffuse, rsurface.modellight_lightdir); - rsurface.ent_flags |= RENDER_LIGHT | RENDER_DYNAMICMODELLIGHT; - } - else - { - VectorSet(rsurface.modellight_ambient, 0, 0, 0); - VectorSet(rsurface.modellight_diffuse, 0, 0, 0); - VectorSet(rsurface.modellight_lightdir, 0, 0, 1); - } - VectorSet(rsurface.colormap_pantscolor, 0, 0, 0); - VectorSet(rsurface.colormap_shirtcolor, 0, 0, 0); - VectorSet(rsurface.colormod, r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale); - rsurface.colormod[3] = 1; - VectorSet(rsurface.glowmod, r_refdef.view.colorscale * r_hdr_glowintensity.value, r_refdef.view.colorscale * r_hdr_glowintensity.value, r_refdef.view.colorscale * r_hdr_glowintensity.value); - memset(rsurface.frameblend, 0, sizeof(rsurface.frameblend)); - rsurface.frameblend[0].lerp = 1; - rsurface.ent_alttextures = false; - rsurface.basepolygonfactor = r_refdef.polygonfactor; - rsurface.basepolygonoffset = r_refdef.polygonoffset; - rsurface.entityskeletaltransform3x4 = NULL; - rsurface.entityskeletaltransform3x4buffer = NULL; - rsurface.entityskeletaltransform3x4offset = 0; - rsurface.entityskeletaltransform3x4size = 0;; - rsurface.entityskeletalnumtransforms = 0; - rsurface.modelvertex3f = model->surfmesh.data_vertex3f; - rsurface.modelvertex3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modelvertex3f_bufferoffset = model->surfmesh.vbooffset_vertex3f; - rsurface.modelsvector3f = model->surfmesh.data_svector3f; - rsurface.modelsvector3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modelsvector3f_bufferoffset = model->surfmesh.vbooffset_svector3f; - rsurface.modeltvector3f = model->surfmesh.data_tvector3f; - rsurface.modeltvector3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modeltvector3f_bufferoffset = model->surfmesh.vbooffset_tvector3f; - rsurface.modelnormal3f = model->surfmesh.data_normal3f; - rsurface.modelnormal3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modelnormal3f_bufferoffset = model->surfmesh.vbooffset_normal3f; - rsurface.modellightmapcolor4f = model->surfmesh.data_lightmapcolor4f; - rsurface.modellightmapcolor4f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modellightmapcolor4f_bufferoffset = model->surfmesh.vbooffset_lightmapcolor4f; - rsurface.modeltexcoordtexture2f = model->surfmesh.data_texcoordtexture2f; - rsurface.modeltexcoordtexture2f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modeltexcoordtexture2f_bufferoffset = model->surfmesh.vbooffset_texcoordtexture2f; - rsurface.modeltexcoordlightmap2f = model->surfmesh.data_texcoordlightmap2f; - rsurface.modeltexcoordlightmap2f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modeltexcoordlightmap2f_bufferoffset = model->surfmesh.vbooffset_texcoordlightmap2f; - rsurface.modelskeletalindex4ub = model->surfmesh.data_skeletalindex4ub; - rsurface.modelskeletalindex4ub_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modelskeletalindex4ub_bufferoffset = model->surfmesh.vbooffset_skeletalindex4ub; - rsurface.modelskeletalweight4ub = model->surfmesh.data_skeletalweight4ub; - rsurface.modelskeletalweight4ub_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modelskeletalweight4ub_bufferoffset = model->surfmesh.vbooffset_skeletalweight4ub; - rsurface.modelelement3i = model->surfmesh.data_element3i; - rsurface.modelelement3i_indexbuffer = model->surfmesh.data_element3i_indexbuffer; - rsurface.modelelement3i_bufferoffset = model->surfmesh.data_element3i_bufferoffset; - rsurface.modelelement3s = model->surfmesh.data_element3s; - rsurface.modelelement3s_indexbuffer = model->surfmesh.data_element3s_indexbuffer; - rsurface.modelelement3s_bufferoffset = model->surfmesh.data_element3s_bufferoffset; - rsurface.modellightmapoffsets = model->surfmesh.data_lightmapoffsets; - rsurface.modelnumvertices = model->surfmesh.num_vertices; - rsurface.modelnumtriangles = model->surfmesh.num_triangles; - rsurface.modelsurfaces = model->data_surfaces; - rsurface.modelvertexmesh = model->surfmesh.data_vertexmesh; - rsurface.modelvertexmesh_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modelvertexmesh_bufferoffset = model->surfmesh.vbooffset_vertex3f; - rsurface.modelgeneratedvertex = false; - rsurface.batchgeneratedvertex = false; - rsurface.batchfirstvertex = 0; - rsurface.batchnumvertices = 0; - rsurface.batchfirsttriangle = 0; - rsurface.batchnumtriangles = 0; - rsurface.batchvertex3f = NULL; - rsurface.batchvertex3f_vertexbuffer = NULL; - rsurface.batchvertex3f_bufferoffset = 0; - rsurface.batchsvector3f = NULL; - rsurface.batchsvector3f_vertexbuffer = NULL; - rsurface.batchsvector3f_bufferoffset = 0; - rsurface.batchtvector3f = NULL; - rsurface.batchtvector3f_vertexbuffer = NULL; - rsurface.batchtvector3f_bufferoffset = 0; - rsurface.batchnormal3f = NULL; - rsurface.batchnormal3f_vertexbuffer = NULL; - rsurface.batchnormal3f_bufferoffset = 0; - rsurface.batchlightmapcolor4f = NULL; - rsurface.batchlightmapcolor4f_vertexbuffer = NULL; - rsurface.batchlightmapcolor4f_bufferoffset = 0; - rsurface.batchtexcoordtexture2f = NULL; - rsurface.batchtexcoordtexture2f_vertexbuffer = NULL; - rsurface.batchtexcoordtexture2f_bufferoffset = 0; - rsurface.batchtexcoordlightmap2f = NULL; - rsurface.batchtexcoordlightmap2f_vertexbuffer = NULL; - rsurface.batchtexcoordlightmap2f_bufferoffset = 0; - rsurface.batchskeletalindex4ub = NULL; - rsurface.batchskeletalindex4ub_vertexbuffer = NULL; - rsurface.batchskeletalindex4ub_bufferoffset = 0; - rsurface.batchskeletalweight4ub = NULL; - rsurface.batchskeletalweight4ub_vertexbuffer = NULL; - rsurface.batchskeletalweight4ub_bufferoffset = 0; - rsurface.batchvertexmesh = NULL; - rsurface.batchvertexmesh_vertexbuffer = NULL; - rsurface.batchvertexmesh_bufferoffset = 0; - rsurface.batchelement3i = NULL; - rsurface.batchelement3i_indexbuffer = NULL; - rsurface.batchelement3i_bufferoffset = 0; - rsurface.batchelement3s = NULL; - rsurface.batchelement3s_indexbuffer = NULL; - rsurface.batchelement3s_bufferoffset = 0; - rsurface.passcolor4f = NULL; - rsurface.passcolor4f_vertexbuffer = NULL; - rsurface.passcolor4f_bufferoffset = 0; - rsurface.forcecurrenttextureupdate = false; -} - void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, qboolean wanttangents, qboolean prepass) { dp_model_t *model = ent->model; @@ -8790,9 +8450,7 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q rsurface.ent_qwskin = (ent->entitynumber <= cl.maxclients && ent->entitynumber >= 1 && cls.protocol == PROTOCOL_QUAKEWORLD && cl.scores[ent->entitynumber - 1].qw_skin[0] && !strcmp(ent->model->name, "progs/player.mdl")) ? (ent->entitynumber - 1) : -1; rsurface.ent_flags = ent->flags; if (r_fullbright_directed.integer && (r_fullbright.integer || !model->lit)) - { rsurface.ent_flags |= RENDER_LIGHT | RENDER_DYNAMICMODELLIGHT; - } rsurface.shadertime = r_refdef.scene.time - ent->shadertime; rsurface.matrix = ent->matrix; rsurface.inversematrix = ent->inversematrix; @@ -8805,14 +8463,6 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q rsurface.fograngerecip = r_refdef.fograngerecip * rsurface.matrixscale; rsurface.fogheightfade = r_refdef.fogheightfade * rsurface.matrixscale; rsurface.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * rsurface.fograngerecip; - VectorCopy(ent->modellight_ambient, rsurface.modellight_ambient); - VectorCopy(ent->modellight_diffuse, rsurface.modellight_diffuse); - VectorCopy(ent->modellight_lightdir, rsurface.modellight_lightdir); - VectorCopy(ent->colormap_pantscolor, rsurface.colormap_pantscolor); - VectorCopy(ent->colormap_shirtcolor, rsurface.colormap_shirtcolor); - VectorScale(ent->colormod, r_refdef.view.colorscale, rsurface.colormod); - rsurface.colormod[3] = ent->alpha; - VectorScale(ent->glowmod, r_refdef.view.colorscale * r_hdr_glowintensity.value, rsurface.glowmod); memcpy(rsurface.frameblend, ent->frameblend, sizeof(ent->frameblend)); rsurface.ent_alttextures = ent->framegroupblend[0].frame != 0; rsurface.basepolygonfactor = r_refdef.polygonfactor; @@ -9055,13 +8705,6 @@ void RSurf_ActiveCustomEntity(const matrix4x4_t *matrix, const matrix4x4_t *inve rsurface.fograngerecip = r_refdef.fograngerecip * rsurface.matrixscale; rsurface.fogheightfade = r_refdef.fogheightfade * rsurface.matrixscale; rsurface.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * rsurface.fograngerecip; - VectorSet(rsurface.modellight_ambient, 0, 0, 0); - VectorSet(rsurface.modellight_diffuse, 0, 0, 0); - VectorSet(rsurface.modellight_lightdir, 0, 0, 1); - VectorSet(rsurface.colormap_pantscolor, 0, 0, 0); - VectorSet(rsurface.colormap_shirtcolor, 0, 0, 0); - Vector4Set(rsurface.colormod, r * r_refdef.view.colorscale, g * r_refdef.view.colorscale, b * r_refdef.view.colorscale, a); - VectorSet(rsurface.glowmod, r_refdef.view.colorscale * r_hdr_glowintensity.value, r_refdef.view.colorscale * r_hdr_glowintensity.value, r_refdef.view.colorscale * r_hdr_glowintensity.value); memset(rsurface.frameblend, 0, sizeof(rsurface.frameblend)); rsurface.frameblend[0].lerp = 1; rsurface.ent_alttextures = false; @@ -10682,9 +10325,9 @@ static void RSurf_DrawBatch_GL11_ApplyAmbient(void) rsurface.passcolor4f_bufferoffset = 0; for (i = 0, c2 = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, c += 4, c2 += 4) { - c2[0] = c[0] + r_refdef.scene.ambient; - c2[1] = c[1] + r_refdef.scene.ambient; - c2[2] = c[2] + r_refdef.scene.ambient; + c2[0] = c[0] + rsurface.texture->render_lightmap_ambient[0]; + c2[1] = c[1] + rsurface.texture->render_lightmap_ambient[1]; + c2[2] = c[2] + rsurface.texture->render_lightmap_ambient[2]; c2[3] = c[3]; } } @@ -10748,7 +10391,7 @@ static void RSurf_DrawBatch_GL11_ClampColor(void) } } -static void RSurf_DrawBatch_GL11_ApplyFakeLight(void) +static void RSurf_DrawBatch_GL11_ApplyFakeLight(float fakelightintensity) { int i; float f; @@ -10766,14 +10409,14 @@ static void RSurf_DrawBatch_GL11_ApplyFakeLight(void) f = -DotProduct(r_refdef.view.forward, n); f = max(0, f); f = f * 0.85 + 0.15; // work around so stuff won't get black - f *= r_refdef.lightmapintensity; + f *= fakelightintensity; Vector4Set(c, f, f, f, 1); } } static void RSurf_DrawBatch_GL11_FakeLight(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog) { - RSurf_DrawBatch_GL11_ApplyFakeLight(); + RSurf_DrawBatch_GL11_ApplyFakeLight(r_refdef.scene.lightmapintensity * r_fakelight_intensity.value); if (applyfog) RSurf_DrawBatch_GL11_ApplyFog(); if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(r, g, b, a); R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, rsurface.passcolor4f_vertexbuffer, rsurface.passcolor4f_bufferoffset); @@ -10781,7 +10424,7 @@ static void RSurf_DrawBatch_GL11_FakeLight(float r, float g, float b, float a, q RSurf_DrawBatch(); } -static void RSurf_DrawBatch_GL11_ApplyVertexShade(float *r, float *g, float *b, float *a, qboolean *applycolor) +static void RSurf_DrawBatch_GL11_ApplyVertexShade(float *r, float *g, float *b, float *a, float lightmapintensity, qboolean *applycolor) { int i; float f; @@ -10794,14 +10437,14 @@ static void RSurf_DrawBatch_GL11_ApplyVertexShade(float *r, float *g, float *b, vec3_t lightdir; // TODO: optimize // model lighting - VectorCopy(rsurface.modellight_lightdir, lightdir); - f = 0.5f * r_refdef.lightmapintensity; - ambientcolor[0] = rsurface.modellight_ambient[0] * *r * f; - ambientcolor[1] = rsurface.modellight_ambient[1] * *g * f; - ambientcolor[2] = rsurface.modellight_ambient[2] * *b * f; - diffusecolor[0] = rsurface.modellight_diffuse[0] * *r * f; - diffusecolor[1] = rsurface.modellight_diffuse[1] * *g * f; - diffusecolor[2] = rsurface.modellight_diffuse[2] * *b * f; + VectorCopy(rsurface.texture->render_modellight_lightdir, lightdir); + f = 0.5f * lightmapintensity; + ambientcolor[0] = rsurface.texture->render_modellight_ambient[0] * *r * f; + ambientcolor[1] = rsurface.texture->render_modellight_ambient[1] * *g * f; + ambientcolor[2] = rsurface.texture->render_modellight_ambient[2] * *b * f; + diffusecolor[0] = rsurface.texture->render_modellight_diffuse[0] * *r * f; + diffusecolor[1] = rsurface.texture->render_modellight_diffuse[1] * *g * f; + diffusecolor[2] = rsurface.texture->render_modellight_diffuse[2] * *b * f; alpha = *a; if (VectorLength2(diffusecolor) > 0) { @@ -10836,7 +10479,7 @@ static void RSurf_DrawBatch_GL11_ApplyVertexShade(float *r, float *g, float *b, static void RSurf_DrawBatch_GL11_VertexShade(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog) { - RSurf_DrawBatch_GL11_ApplyVertexShade(&r, &g, &b, &a, &applycolor); + RSurf_DrawBatch_GL11_ApplyVertexShade(&r, &g, &b, &a, r_refdef.scene.lightmapintensity, &applycolor); if (applyfog) RSurf_DrawBatch_GL11_ApplyFog(); if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(r, g, b, a); R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, rsurface.passcolor4f_vertexbuffer, rsurface.passcolor4f_bufferoffset); @@ -10933,7 +10576,7 @@ static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, const msurface { // render screenspace normalmap to texture GL_DepthMask(true); - R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_DEFERREDGEOMETRY, texturenumsurfaces, texturesurfacelist, NULL, false); + R_SetupShader_Surface(vec3_origin, vec3_origin, vec3_origin, RSURFPASS_DEFERREDGEOMETRY, texturenumsurfaces, texturesurfacelist, NULL, false); RSurf_DrawBatch(); return; } @@ -10961,18 +10604,18 @@ static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, const msurface { // render water or distortion background GL_DepthMask(true); - R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BACKGROUND, end-start, texturesurfacelist + start, (void *)(r_fb.water.waterplanes + startplaneindex), false); + R_SetupShader_Surface(vec3_origin, vec3_origin, vec3_origin, RSURFPASS_BACKGROUND, end-start, texturesurfacelist + start, (void *)(r_fb.water.waterplanes + startplaneindex), false); RSurf_DrawBatch(); // blend surface on top GL_DepthMask(false); - R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, end-start, texturesurfacelist + start, NULL, false); + R_SetupShader_Surface(vec3_origin, vec3_origin, vec3_origin, RSURFPASS_BASE, end-start, texturesurfacelist + start, NULL, false); RSurf_DrawBatch(); } else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)) { // render surface with reflection texture as input GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)); - R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, end-start, texturesurfacelist + start, (void *)(r_fb.water.waterplanes + startplaneindex), false); + R_SetupShader_Surface(vec3_origin, vec3_origin, vec3_origin, RSURFPASS_BASE, end-start, texturesurfacelist + start, (void *)(r_fb.water.waterplanes + startplaneindex), false); RSurf_DrawBatch(); } } @@ -10981,7 +10624,7 @@ static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, const msurface // render surface batch normally GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)); - R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, texturenumsurfaces, texturesurfacelist, NULL, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) != 0); + R_SetupShader_Surface(vec3_origin, vec3_origin, vec3_origin, RSURFPASS_BASE, texturenumsurfaces, texturesurfacelist, NULL, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) != 0); RSurf_DrawBatch(); } @@ -10992,7 +10635,7 @@ static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, const msurface qboolean applyfog; int layerindex; const texturelayer_t *layer; - RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | ((!rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.modeltexcoordlightmap2f ? BATCHNEED_ARRAY_LIGHTMAP : 0) | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist); + RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | ((!rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)) ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.modeltexcoordlightmap2f ? BATCHNEED_ARRAY_LIGHTMAP : 0) | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist); R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset); for (layerindex = 0, layer = rsurface.texture->currentlayers;layerindex < rsurface.texture->currentnumlayers;layerindex++, layer++) @@ -11099,7 +10742,7 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, const msurface qboolean applyfog; int layerindex; const texturelayer_t *layer; - RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | ((!rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.modeltexcoordlightmap2f ? BATCHNEED_ARRAY_LIGHTMAP : 0) | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist); + RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | ((!rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)) ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.modeltexcoordlightmap2f ? BATCHNEED_ARRAY_LIGHTMAP : 0) | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist); R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset); for (layerindex = 0, layer = rsurface.texture->currentlayers;layerindex < rsurface.texture->currentnumlayers;layerindex++, layer++) @@ -11204,14 +10847,15 @@ static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, const int j; r_vertexgeneric_t *batchvertex; float c[4]; + texture_t *t = rsurface.texture; // R_Mesh_ResetTextureState(); R_SetupShader_Generic_NoTexture(false, false); - if(rsurface.texture && rsurface.texture->currentskinframe) + if(t && t->currentskinframe) { - memcpy(c, rsurface.texture->currentskinframe->avgcolor, sizeof(c)); - c[3] *= rsurface.texture->currentalpha; + memcpy(c, t->currentskinframe->avgcolor, sizeof(c)); + c[3] *= t->currentalpha; } else { @@ -11221,11 +10865,11 @@ static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, const c[3] = 1; } - if (rsurface.texture->pantstexture || rsurface.texture->shirttexture) + if (t->pantstexture || t->shirttexture) { - c[0] = 0.5 * (rsurface.colormap_pantscolor[0] * 0.3 + rsurface.colormap_shirtcolor[0] * 0.7); - c[1] = 0.5 * (rsurface.colormap_pantscolor[1] * 0.3 + rsurface.colormap_shirtcolor[1] * 0.7); - c[2] = 0.5 * (rsurface.colormap_pantscolor[2] * 0.3 + rsurface.colormap_shirtcolor[2] * 0.7); + c[0] = 0.5 * (t->render_colormap_pants[0] * 0.3 + t->render_colormap_shirt[0] * 0.7); + c[1] = 0.5 * (t->render_colormap_pants[1] * 0.3 + t->render_colormap_shirt[1] * 0.7); + c[2] = 0.5 * (t->render_colormap_pants[2] * 0.3 + t->render_colormap_shirt[2] * 0.7); } // brighten it up (as texture value 127 means "unlit") @@ -11233,27 +10877,27 @@ static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, const c[1] *= 2 * r_refdef.view.colorscale; c[2] *= 2 * r_refdef.view.colorscale; - if(rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA) + if(t->currentmaterialflags & MATERIALFLAG_WATERALPHA) c[3] *= r_wateralpha.value; - if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHA && c[3] != 1) + if(t->currentmaterialflags & MATERIALFLAG_ALPHA && c[3] != 1) { GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GL_DepthMask(false); } - else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD) + else if(t->currentmaterialflags & MATERIALFLAG_ADD) { GL_BlendFunc(GL_ONE, GL_ONE); GL_DepthMask(false); } - else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) + else if(t->currentmaterialflags & MATERIALFLAG_ALPHATEST) { GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // can't do alpha test without texture, so let's blend instead GL_DepthMask(false); } - else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND) + else if(t->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND) { - GL_BlendFunc(rsurface.texture->customblendfunc[0], rsurface.texture->customblendfunc[1]); + GL_BlendFunc(t->customblendfunc[0], t->customblendfunc[1]); GL_DepthMask(false); } else @@ -11266,32 +10910,20 @@ static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, const { rsurface.passcolor4f = NULL; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) - { - RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist); - - rsurface.passcolor4f = NULL; - rsurface.passcolor4f_vertexbuffer = 0; - rsurface.passcolor4f_bufferoffset = 0; - } - else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) + if (t->currentmaterialflags & MATERIALFLAG_MODELLIGHT) { qboolean applycolor = true; float one = 1.0; RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist); - r_refdef.lightmapintensity = 1; - RSurf_DrawBatch_GL11_ApplyVertexShade(&one, &one, &one, &one, &applycolor); - r_refdef.lightmapintensity = 0; // we're in showsurfaces, after all + RSurf_DrawBatch_GL11_ApplyVertexShade(&one, &one, &one, &one, 1.0f, &applycolor); } else if (FAKELIGHT_ENABLED) { RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist); - r_refdef.lightmapintensity = r_fakelight_intensity.value; - RSurf_DrawBatch_GL11_ApplyFakeLight(); - r_refdef.lightmapintensity = 0; // we're in showsurfaces, after all + RSurf_DrawBatch_GL11_ApplyFakeLight(r_fakelight_intensity.value); } else { @@ -11300,12 +10932,12 @@ static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, const rsurface.passcolor4f = rsurface.batchlightmapcolor4f; rsurface.passcolor4f_vertexbuffer = rsurface.batchlightmapcolor4f_vertexbuffer; rsurface.passcolor4f_bufferoffset = rsurface.batchlightmapcolor4f_bufferoffset; + RSurf_DrawBatch_GL11_ApplyAmbient(); } if(!rsurface.passcolor4f) RSurf_DrawBatch_GL11_MakeFullbrightLightmapColorArray(); - RSurf_DrawBatch_GL11_ApplyAmbient(); RSurf_DrawBatch_GL11_ApplyColor(c[0], c[1], c[2], c[3]); if(r_refdef.fogenabled) RSurf_DrawBatch_GL11_ApplyFogToFinishedVertexColors(); @@ -11384,36 +11016,6 @@ static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, const } } -static void R_DrawWorldTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean prepass) -{ - CHECKGLERROR - RSurf_SetupDepthAndCulling(); - if (r_showsurfaces.integer) - { - R_DrawTextureSurfaceList_ShowSurfaces(texturenumsurfaces, texturesurfacelist, writedepth); - return; - } - switch (vid.renderpath) - { - case RENDERPATH_GL20: - case RENDERPATH_D3D9: - case RENDERPATH_D3D10: - case RENDERPATH_D3D11: - case RENDERPATH_SOFT: - case RENDERPATH_GLES2: - R_DrawTextureSurfaceList_GL20(texturenumsurfaces, texturesurfacelist, writedepth, prepass); - break; - case RENDERPATH_GL13: - case RENDERPATH_GLES1: - R_DrawTextureSurfaceList_GL13(texturenumsurfaces, texturesurfacelist, writedepth); - break; - case RENDERPATH_GL11: - R_DrawTextureSurfaceList_GL11(texturenumsurfaces, texturesurfacelist, writedepth); - break; - } - CHECKGLERROR -} - static void R_DrawModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean prepass) { CHECKGLERROR @@ -11452,12 +11054,7 @@ static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const const msurface_t *surface; const msurface_t *texturesurfacelist[MESHQUEUE_TRANSPARENT_BATCHSIZE]; - // if the model is static it doesn't matter what value we give for - // wantnormals and wanttangents, so this logic uses only rules applicable - // to a model, knowing that they are meaningless otherwise - if (ent == r_refdef.scene.worldentity) - RSurf_ActiveWorldEntity(); - else if (r_showsurfaces.integer && r_showsurfaces.integer != 3) + if (r_showsurfaces.integer && r_showsurfaces.integer != 3) RSurf_ActiveModelEntity(ent, false, false, false); else { @@ -11562,12 +11159,9 @@ static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const } } // render the range of surfaces - if (ent == r_refdef.scene.worldentity) - R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, false, false); - else - R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, false, false); + R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, false, false); } - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity + rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity } static void R_ProcessTransparentTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist) @@ -11615,84 +11209,6 @@ static void R_DrawTextureSurfaceList_DepthOnly(int texturenumsurfaces, const msu RSurf_DrawBatch(); } -static void R_ProcessWorldTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, qboolean prepass) -{ - CHECKGLERROR - if (depthonly) - R_DrawTextureSurfaceList_DepthOnly(texturenumsurfaces, texturesurfacelist); - else if (prepass) - { - if (!rsurface.texture->currentnumlayers) - return; - if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) - R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist); - else - R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass); - } - else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) && (!r_showsurfaces.integer || r_showsurfaces.integer == 3)) - R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist); - else if (!rsurface.texture->currentnumlayers) - return; - else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)))) - { - // in the deferred case, transparent surfaces were queued during prepass - if (!r_shadow_usingdeferredprepass) - R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist); - } - else - { - // the alphatest check is to make sure we write depth for anything we skipped on the depth-only pass earlier - R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth || (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST), prepass); - } - CHECKGLERROR -} - -static void R_QueueWorldSurfaceList(int numsurfaces, const msurface_t **surfacelist, int flagsmask, qboolean writedepth, qboolean depthonly, qboolean prepass) -{ - int i, j; - texture_t *texture; - R_FrameData_SetMark(); - // break the surface list down into batches by texture and use of lightmapping - for (i = 0;i < numsurfaces;i = j) - { - j = i + 1; - // texture is the base texture pointer, rsurface.texture is the - // current frame/skin the texture is directing us to use (for example - // if a model has 2 skins and it is on skin 1, then skin 0 tells us to - // use skin 1 instead) - texture = surfacelist[i]->texture; - rsurface.texture = R_GetCurrentTexture(texture); - if (!(rsurface.texture->currentmaterialflags & flagsmask) || (rsurface.texture->currentmaterialflags & MATERIALFLAG_NODRAW)) - { - // if this texture is not the kind we want, skip ahead to the next one - for (;j < numsurfaces && texture == surfacelist[j]->texture;j++) - ; - continue; - } - if(FAKELIGHT_ENABLED || depthonly || prepass) - { - rsurface.lightmaptexture = NULL; - rsurface.deluxemaptexture = NULL; - rsurface.uselightmaptexture = false; - // simply scan ahead until we find a different texture or lightmap state - for (;j < numsurfaces && texture == surfacelist[j]->texture;j++) - ; - } - else - { - rsurface.lightmaptexture = surfacelist[i]->lightmaptexture; - rsurface.deluxemaptexture = surfacelist[i]->deluxemaptexture; - rsurface.uselightmaptexture = surfacelist[i]->lightmaptexture != NULL; - // simply scan ahead until we find a different texture or lightmap state - for (;j < numsurfaces && texture == surfacelist[j]->texture && rsurface.lightmaptexture == surfacelist[j]->lightmaptexture;j++) - ; - } - // render the range of surfaces - R_ProcessWorldTextureSurfaceList(j - i, surfacelist + i, writedepth, depthonly, prepass); - } - R_FrameData_ReturnToMark(); -} - static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, qboolean prepass) { CHECKGLERROR @@ -12358,10 +11874,7 @@ static void R_DrawModelDecals_Entity(entity_render_t *ent) // if the model is static it doesn't matter what value we give for // wantnormals and wanttangents, so this logic uses only rules applicable // to a model, knowing that they are meaningless otherwise - if (ent == r_refdef.scene.worldentity) - RSurf_ActiveWorldEntity(); - else - RSurf_ActiveModelEntity(ent, false, false, false); + RSurf_ActiveModelEntity(ent, false, false, false); decalsystem->lastupdatetime = r_refdef.scene.time; @@ -12714,101 +12227,6 @@ static void R_DrawDebugModel(void) int r_maxsurfacelist = 0; const msurface_t **r_surfacelist = NULL; -void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean debug, qboolean prepass) -{ - int i, j, endj, flagsmask; - dp_model_t *model = r_refdef.scene.worldmodel; - msurface_t *surfaces; - unsigned char *update; - int numsurfacelist = 0; - if (model == NULL) - return; - - if (r_maxsurfacelist < model->num_surfaces) - { - r_maxsurfacelist = model->num_surfaces; - if (r_surfacelist) - Mem_Free((msurface_t**)r_surfacelist); - r_surfacelist = (const msurface_t **) Mem_Alloc(r_main_mempool, r_maxsurfacelist * sizeof(*r_surfacelist)); - } - - RSurf_ActiveWorldEntity(); - - surfaces = model->data_surfaces; - update = model->brushq1.lightmapupdateflags; - - // update light styles on this submodel - if (!skysurfaces && !depthonly && !prepass && model->brushq1.num_lightstyles && r_refdef.lightmapintensity > 0) - { - model_brush_lightstyleinfo_t *style; - for (i = 0, style = model->brushq1.data_lightstyleinfo;i < model->brushq1.num_lightstyles;i++, style++) - { - if (style->value != r_refdef.scene.lightstylevalue[style->style]) - { - int *list = style->surfacelist; - style->value = r_refdef.scene.lightstylevalue[style->style]; - for (j = 0;j < style->numsurfaces;j++) - update[list[j]] = true; - } - } - } - - flagsmask = skysurfaces ? MATERIALFLAG_SKY : MATERIALFLAG_WALL; - - if (debug) - { - R_DrawDebugModel(); - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity - return; - } - - rsurface.lightmaptexture = NULL; - rsurface.deluxemaptexture = NULL; - rsurface.uselightmaptexture = false; - rsurface.texture = NULL; - rsurface.rtlight = NULL; - numsurfacelist = 0; - // add visible surfaces to draw list - for (i = 0;i < model->nummodelsurfaces;i++) - { - j = model->sortedmodelsurfaces[i]; - if (r_refdef.viewcache.world_surfacevisible[j]) - r_surfacelist[numsurfacelist++] = surfaces + j; - } - // update lightmaps if needed - if (model->brushq1.firstrender) - { - model->brushq1.firstrender = false; - for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++) - if (update[j]) - R_BuildLightMap(r_refdef.scene.worldentity, surfaces + j); - } - else if (update) - { - for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++) - if (r_refdef.viewcache.world_surfacevisible[j]) - if (update[j]) - R_BuildLightMap(r_refdef.scene.worldentity, surfaces + j); - } - // don't do anything if there were no surfaces - if (!numsurfacelist) - { - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity - return; - } - R_QueueWorldSurfaceList(numsurfacelist, r_surfacelist, flagsmask, writedepth, depthonly, prepass); - - // add to stats if desired - if (r_speeds.integer && !skysurfaces && !depthonly) - { - r_refdef.stats[r_stat_world_surfaces] += numsurfacelist; - for (j = 0;j < numsurfacelist;j++) - r_refdef.stats[r_stat_world_triangles] += r_surfacelist[j]->num_triangles; - } - - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity -} - void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean debug, qboolean prepass) { int i, j, endj, flagsmask; @@ -12827,12 +12245,7 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr r_surfacelist = (const msurface_t **) Mem_Alloc(r_main_mempool, r_maxsurfacelist * sizeof(*r_surfacelist)); } - // if the model is static it doesn't matter what value we give for - // wantnormals and wanttangents, so this logic uses only rules applicable - // to a model, knowing that they are meaningless otherwise - if (ent == r_refdef.scene.worldentity) - RSurf_ActiveWorldEntity(); - else if (r_showsurfaces.integer && r_showsurfaces.integer != 3) + if (r_showsurfaces.integer && r_showsurfaces.integer != 3) RSurf_ActiveModelEntity(ent, false, false, false); else if (prepass) RSurf_ActiveModelEntity(ent, true, true, true); @@ -12879,7 +12292,7 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr update = model->brushq1.lightmapupdateflags; // update light styles - if (!skysurfaces && !depthonly && !prepass && model->brushq1.num_lightstyles && r_refdef.lightmapintensity > 0) + if (!skysurfaces && !depthonly && !prepass && model->brushq1.num_lightstyles && r_refdef.scene.lightmapintensity > 0) { model_brush_lightstyleinfo_t *style; for (i = 0, style = model->brushq1.data_lightstyleinfo;i < model->brushq1.num_lightstyles;i++, style++) @@ -12899,7 +12312,7 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr if (debug) { R_DrawDebugModel(); - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity + rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity return; } @@ -12910,12 +12323,26 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr rsurface.rtlight = NULL; numsurfacelist = 0; // add visible surfaces to draw list - for (i = 0;i < model->nummodelsurfaces;i++) - r_surfacelist[numsurfacelist++] = surfaces + model->sortedmodelsurfaces[i]; + if (ent == r_refdef.scene.worldentity) + { + // for the world entity, check surfacevisible + for (i = 0;i < model->nummodelsurfaces;i++) + { + j = model->sortedmodelsurfaces[i]; + if (r_refdef.viewcache.world_surfacevisible[j]) + r_surfacelist[numsurfacelist++] = surfaces + j; + } + } + else + { + // add all surfaces + for (i = 0; i < model->nummodelsurfaces; i++) + r_surfacelist[numsurfacelist++] = surfaces + model->sortedmodelsurfaces[i]; + } // don't do anything if there were no surfaces if (!numsurfacelist) { - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity + rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity return; } // update lightmaps if needed @@ -12942,11 +12369,12 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr r_refdef.stats[r_stat_entities_triangles] += r_surfacelist[j]->num_triangles; } - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity + rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity } void R_DrawCustomSurface(skinframe_t *skinframe, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qboolean writedepth, qboolean prepass) { + int q; static texture_t texture; static msurface_t surface; const msurface_t *surfacelist = &surface; @@ -12966,6 +12394,21 @@ void R_DrawCustomSurface(skinframe_t *skinframe, const matrix4x4_t *texmatrix, i // WHEN ADDING DEFAULTS HERE, REMEMBER TO PUT DEFAULTS IN ALL LOADERS // JUST GREP FOR "specularscalemod = 1". + for (q = 0; q < 3; q++) + { + texture.render_glowmod[q] = r_refdef.view.colorscale * r_hdr_glowintensity.value; + texture.render_modellight_lightdir[q] = q == 2; + texture.render_modellight_ambient[q] = r_refdef.view.colorscale * r_refdef.scene.ambientintensity; + texture.render_modellight_diffuse[q] = r_refdef.view.colorscale; + texture.render_modellight_specular[q] = r_refdef.view.colorscale; + texture.render_lightmap_ambient[q] = r_refdef.view.colorscale * r_refdef.scene.ambientintensity; + texture.render_lightmap_diffuse[q] = r_refdef.view.colorscale * r_refdef.scene.lightmapintensity; + texture.render_lightmap_specular[q] = r_refdef.view.colorscale; + texture.render_rtlight_diffuse[q] = r_refdef.view.colorscale; + texture.render_rtlight_specular[q] = r_refdef.view.colorscale; + } + texture.currentalpha = 1.0f; + surface.texture = &texture; surface.num_triangles = numtriangles; surface.num_firsttriangle = firsttriangle; diff --git a/gl_rsurf.c b/gl_rsurf.c index 0c9e85dc..0bec0bde 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -583,10 +583,7 @@ void R_Q1BSP_DrawSky(entity_render_t *ent) { if (ent->model == NULL) return; - if (ent == r_refdef.scene.worldentity) - R_DrawWorldSurfaces(true, true, false, false, false); - else - R_DrawModelSurfaces(ent, true, true, false, false, false); + R_DrawModelSurfaces(ent, true, true, false, false, false); } void R_Q1BSP_DrawAddWaterPlanes(entity_render_t *ent) @@ -597,10 +594,7 @@ void R_Q1BSP_DrawAddWaterPlanes(entity_render_t *ent) if (model == NULL) return; - if (ent == r_refdef.scene.worldentity) - RSurf_ActiveWorldEntity(); - else - RSurf_ActiveModelEntity(ent, true, false, false); + RSurf_ActiveModelEntity(ent, true, false, false); surfaces = model->data_surfaces; flagsmask = MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA; @@ -629,7 +623,7 @@ void R_Q1BSP_DrawAddWaterPlanes(entity_render_t *ent) R_Water_AddWaterPlane(surfaces + j, n); } } - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity + rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity } void R_Q1BSP_Draw(entity_render_t *ent) @@ -637,10 +631,7 @@ void R_Q1BSP_Draw(entity_render_t *ent) dp_model_t *model = ent->model; if (model == NULL) return; - if (ent == r_refdef.scene.worldentity) - R_DrawWorldSurfaces(false, true, false, false, false); - else - R_DrawModelSurfaces(ent, false, true, false, false, false); + R_DrawModelSurfaces(ent, false, true, false, false, false); } void R_Q1BSP_DrawDepth(entity_render_t *ent) @@ -654,10 +645,7 @@ void R_Q1BSP_DrawDepth(entity_render_t *ent) GL_BlendFunc(GL_ONE, GL_ZERO); GL_DepthMask(true); // R_Mesh_ResetTextureState(); - if (ent == r_refdef.scene.worldentity) - R_DrawWorldSurfaces(false, false, true, false, false); - else - R_DrawModelSurfaces(ent, false, false, true, false, false); + R_DrawModelSurfaces(ent, false, false, true, false, false); GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1); } @@ -665,10 +653,7 @@ void R_Q1BSP_DrawDebug(entity_render_t *ent) { if (ent->model == NULL) return; - if (ent == r_refdef.scene.worldentity) - R_DrawWorldSurfaces(false, false, false, true, false); - else - R_DrawModelSurfaces(ent, false, false, false, true, false); + R_DrawModelSurfaces(ent, false, false, false, true, false); } void R_Q1BSP_DrawPrepass(entity_render_t *ent) @@ -676,10 +661,7 @@ void R_Q1BSP_DrawPrepass(entity_render_t *ent) dp_model_t *model = ent->model; if (model == NULL) return; - if (ent == r_refdef.scene.worldentity) - R_DrawWorldSurfaces(false, true, false, false, true); - else - R_DrawModelSurfaces(ent, false, true, false, false, true); + R_DrawModelSurfaces(ent, false, true, false, false, true); } typedef struct r_q1bsp_getlightinfo_s @@ -1257,7 +1239,7 @@ void R_Q1BSP_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, floa info.pvs = info.model->brush.GetPVS(info.model, info.relativelightorigin); else info.pvs = NULL; - RSurf_ActiveWorldEntity(); + RSurf_ActiveModelEntity(r_refdef.scene.worldentity, false, false, false); if (!info.noocclusion && r_shadow_compilingrtlight && r_shadow_realtime_world_compileportalculling.integer && info.model->brush.data_portals) { @@ -1278,7 +1260,7 @@ void R_Q1BSP_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, floa R_Q1BSP_CallRecursiveGetLightInfo(&info, !info.noocclusion && (r_shadow_compilingrtlight ? r_shadow_realtime_world_compilesvbsp.integer : r_shadow_realtime_dlight_svbspculling.integer) != 0); } - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity + rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity // limit combined leaf box to light boundaries outmins[0] = max(info.outmins[0] - 1, info.lightmins[0]); @@ -1518,7 +1500,7 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surface ; // now figure out what to do with this particular range of surfaces // VorteX: added MATERIALFLAG_NORTLIGHT - if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WALL | MATERIALFLAG_FULLBRIGHT | MATERIALFLAG_NORTLIGHT)) != MATERIALFLAG_WALL) + if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WALL | MATERIALFLAG_NORTLIGHT)) != MATERIALFLAG_WALL) continue; if (r_fb.water.renderingscene && (rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))) continue; diff --git a/model_brush.h b/model_brush.h index fb167321..2eb38470 100644 --- a/model_brush.h +++ b/model_brush.h @@ -115,15 +115,13 @@ mplane_t; #define MATERIALFLAG_REFLECTION 0x00100000 // use model lighting on this material (q1bsp lightmap sampling or q3bsp lightgrid, implies FULLBRIGHT is false) #define MATERIALFLAG_MODELLIGHT 0x00200000 -// add directional model lighting to this material (q3bsp lightgrid only) -#define MATERIALFLAG_MODELLIGHT_DIRECTIONAL 0x00400000 // causes RSurf_GetCurrentTexture to leave alone certain fields #define MATERIALFLAG_CUSTOMSURFACE 0x00800000 // causes MATERIALFLAG_BLENDED to render a depth pass before rendering, hiding backfaces and other hidden geometry #define MATERIALFLAG_TRANSDEPTH 0x01000000 // like refraction, but doesn't distort etc. #define MATERIALFLAG_CAMERA 0x02000000 -// disable rtlight on surface, use R_LightPoint instead +// disable rtlight on surface - does not disable other types of lighting (LIGHTMAP, MODELLIGHT) #define MATERIALFLAG_NORTLIGHT 0x04000000 // alphagen vertex #define MATERIALFLAG_ALPHAGEN_VERTEX 0x08000000 diff --git a/model_shared.h b/model_shared.h index f48a1bbd..9ccae5c3 100644 --- a/model_shared.h +++ b/model_shared.h @@ -614,14 +614,29 @@ typedef struct texture_s rtexture_t *backgroundnmaptexture; // normalmap (bumpmap for dot3) rtexture_t *backgroundglosstexture; // glossmap (for dot3) rtexture_t *backgroundglowtexture; // glow only (fullbrights) - float specularscale; float specularpower; - // color tint (colormod * currentalpha) used for rtlighting this material - float dlightcolor[3]; - // color tint (colormod * 2) used for lightmapped lighting on this material - // includes alpha as 4th component - // replaces role of gl_Color in GLSL shader - float lightmapcolor[4]; + + // rendering parameters - updated by R_GetCurrentTexture using rsurface.render_* fields + // (almost) all map textures are lightmap (no MATERIALFLAG_MODELLIGHT set), + // (almost) all model textures are MATERIALFLAG_MODELLIGHT, + // MATERIALFLAG_FULLBRIGHT is rendered as a forced MATERIALFLAG_MODELLIGHT with rtlights disabled + float render_glowmod[3]; + // MATERIALFLAG_MODELLIGHT uses these parameters + float render_modellight_ambient[3]; + float render_modellight_diffuse[3]; + float render_modellight_lightdir[3]; + float render_modellight_specular[3]; + // lightmap rendering (not MATERIALFLAG_MODELLIGHT) + float render_lightmap_ambient[3]; + float render_lightmap_diffuse[3]; + float render_lightmap_specular[3]; + // rtlights use these colors for the materials on this entity + float render_rtlight_diffuse[3]; + float render_rtlight_specular[3]; + // tint applied on top of render_*_diffuse for pants layer + float render_colormap_pants[3]; + // tint applied on top of render_*_diffuse for shirt layer + float render_colormap_shirt[3]; // from q3 shaders int customblendfunc[2]; diff --git a/mvm_cmds.c b/mvm_cmds.c index ace22bfa..a310b0e7 100644 --- a/mvm_cmds.c +++ b/mvm_cmds.c @@ -1624,7 +1624,8 @@ void MVM_init_cmd(prvm_prog_t *prog) scene->maxentities = MAX_EDICTS + 256 + 512; scene->entities = (entity_render_t **)Mem_Alloc(prog->progs_mempool, sizeof(entity_render_t *) * scene->maxentities); - scene->ambient = 32.0f; + // LadyHavoc: what is this for? + scene->ambientintensity = 32.0f; } void MVM_reset_cmd(prvm_prog_t *prog) diff --git a/r_shadow.c b/r_shadow.c index 9a5ab0a9..d767804a 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -3879,10 +3879,10 @@ static void R_Shadow_RenderLighting_VisibleLighting(int texturenumsurfaces, cons RSurf_DrawBatch(); } -static void R_Shadow_RenderLighting_Light_GLSL(int texturenumsurfaces, const msurface_t **texturesurfacelist, const vec3_t lightcolor, float ambientscale, float diffusescale, float specularscale) +static void R_Shadow_RenderLighting_Light_GLSL(int texturenumsurfaces, const msurface_t **texturesurfacelist, const float ambientcolor[3], const float diffusecolor[3], const float specularcolor[3]) { // ARB2 GLSL shader path (GFFX5200, Radeon 9500) - R_SetupShader_Surface(lightcolor, false, ambientscale, diffusescale, specularscale, RSURFPASS_RTLIGHT, texturenumsurfaces, texturesurfacelist, NULL, false); + R_SetupShader_Surface(ambientcolor, diffusecolor, specularcolor, RSURFPASS_RTLIGHT, texturenumsurfaces, texturesurfacelist, NULL, false); RSurf_DrawBatch(); } @@ -3975,29 +3975,26 @@ static void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numve } } -static void R_Shadow_RenderLighting_Light_Vertex(int texturenumsurfaces, const msurface_t **texturesurfacelist, const vec3_t lightcolor, float ambientscale, float diffusescale) +static void R_Shadow_RenderLighting_Light_Vertex(int texturenumsurfaces, const msurface_t **texturesurfacelist, const float ambientcolor[3], const float diffusecolor[3]) { // OpenGL 1.1 path (anything) float ambientcolorbase[3], diffusecolorbase[3]; float ambientcolorpants[3], diffusecolorpants[3]; float ambientcolorshirt[3], diffusecolorshirt[3]; - const float *surfacecolor = rsurface.texture->dlightcolor; - const float *surfacepants = rsurface.colormap_pantscolor; - const float *surfaceshirt = rsurface.colormap_shirtcolor; + const float *surfacepants = rsurface.texture->render_colormap_pants; + const float *surfaceshirt = rsurface.texture->render_colormap_shirt; rtexture_t *basetexture = rsurface.texture->basetexture; rtexture_t *pantstexture = rsurface.texture->pantstexture; rtexture_t *shirttexture = rsurface.texture->shirttexture; qboolean dopants = pantstexture && VectorLength2(surfacepants) >= (1.0f / 1048576.0f); qboolean doshirt = shirttexture && VectorLength2(surfaceshirt) >= (1.0f / 1048576.0f); - ambientscale *= 2 * r_refdef.view.colorscale; - diffusescale *= 2 * r_refdef.view.colorscale; - ambientcolorbase[0] = lightcolor[0] * ambientscale * surfacecolor[0];ambientcolorbase[1] = lightcolor[1] * ambientscale * surfacecolor[1];ambientcolorbase[2] = lightcolor[2] * ambientscale * surfacecolor[2]; - diffusecolorbase[0] = lightcolor[0] * diffusescale * surfacecolor[0];diffusecolorbase[1] = lightcolor[1] * diffusescale * surfacecolor[1];diffusecolorbase[2] = lightcolor[2] * diffusescale * surfacecolor[2]; + VectorCopy(ambientcolor, ambientcolorbase); + VectorCopy(diffusecolor, diffusecolorbase); ambientcolorpants[0] = ambientcolorbase[0] * surfacepants[0];ambientcolorpants[1] = ambientcolorbase[1] * surfacepants[1];ambientcolorpants[2] = ambientcolorbase[2] * surfacepants[2]; diffusecolorpants[0] = diffusecolorbase[0] * surfacepants[0];diffusecolorpants[1] = diffusecolorbase[1] * surfacepants[1];diffusecolorpants[2] = diffusecolorbase[2] * surfacepants[2]; ambientcolorshirt[0] = ambientcolorbase[0] * surfaceshirt[0];ambientcolorshirt[1] = ambientcolorbase[1] * surfaceshirt[1];ambientcolorshirt[2] = ambientcolorbase[2] * surfaceshirt[2]; diffusecolorshirt[0] = diffusecolorbase[0] * surfaceshirt[0];diffusecolorshirt[1] = diffusecolorbase[1] * surfaceshirt[1];diffusecolorshirt[2] = diffusecolorbase[2] * surfaceshirt[2]; - RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | (diffusescale > 0 ? BATCHNEED_ARRAY_NORMAL : 0) | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist); + RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | (VectorLength2(diffusecolor) > 0 ? BATCHNEED_ARRAY_NORMAL : 0) | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist); rsurface.passcolor4f = (float *)R_FrameData_Alloc((rsurface.batchfirstvertex + rsurface.batchnumvertices) * sizeof(float[4])); R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset); R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, 0, 0); @@ -4047,25 +4044,28 @@ static void R_Shadow_RenderLighting_Light_Vertex(int texturenumsurfaces, const m extern cvar_t gl_lightmaps; void R_Shadow_RenderLighting(int texturenumsurfaces, const msurface_t **texturesurfacelist) { - float ambientscale, diffusescale, specularscale; qboolean negated; - float lightcolor[3]; - VectorCopy(rsurface.rtlight->currentcolor, lightcolor); - ambientscale = rsurface.rtlight->ambientscale + rsurface.texture->rtlightambient; - diffusescale = rsurface.rtlight->diffusescale * max(0, 1.0 - rsurface.texture->rtlightambient); - specularscale = rsurface.rtlight->specularscale * rsurface.texture->specularscale; + float ambientcolor[3], diffusecolor[3], specularcolor[3]; + VectorM(rsurface.rtlight->ambientscale + rsurface.texture->rtlightambient, rsurface.texture->render_rtlight_diffuse, ambientcolor); + VectorM(rsurface.rtlight->diffusescale * max(0, 1.0 - rsurface.texture->rtlightambient), rsurface.texture->render_rtlight_diffuse, diffusecolor); + VectorM(rsurface.rtlight->specularscale, rsurface.texture->render_rtlight_specular, specularcolor); if (!r_shadow_usenormalmap.integer) { - ambientscale += 1.0f * diffusescale; - diffusescale = 0; - specularscale = 0; + VectorMAM(1.0f, ambientcolor, 1.0f, diffusecolor, ambientcolor); + VectorClear(diffusecolor); + VectorClear(specularcolor); } - if ((ambientscale + diffusescale) * VectorLength2(lightcolor) + specularscale * VectorLength2(lightcolor) < (1.0f / 1048576.0f)) + VectorMultiply(ambientcolor, rsurface.rtlight->currentcolor, ambientcolor); + VectorMultiply(diffusecolor, rsurface.rtlight->currentcolor, diffusecolor); + VectorMultiply(specularcolor, rsurface.rtlight->currentcolor, specularcolor); + if (VectorLength2(ambientcolor) + VectorLength2(diffusecolor) + VectorLength2(specularcolor) < (1.0f / 1048576.0f)) return; - negated = (lightcolor[0] + lightcolor[1] + lightcolor[2] < 0) && vid.support.ext_blend_subtract; + negated = (rsurface.rtlight->currentcolor[0] + rsurface.rtlight->currentcolor[1] + rsurface.rtlight->currentcolor[2] < 0) && vid.support.ext_blend_subtract; if(negated) { - VectorNegate(lightcolor, lightcolor); + VectorNegate(ambientcolor, ambientcolor); + VectorNegate(diffusecolor, diffusecolor); + VectorNegate(specularcolor, specularcolor); GL_BlendEquationSubtract(true); } RSurf_SetupDepthAndCulling(); @@ -4076,13 +4076,13 @@ void R_Shadow_RenderLighting(int texturenumsurfaces, const msurface_t **textures R_Shadow_RenderLighting_VisibleLighting(texturenumsurfaces, texturesurfacelist); break; case R_SHADOW_RENDERMODE_LIGHT_GLSL: - R_Shadow_RenderLighting_Light_GLSL(texturenumsurfaces, texturesurfacelist, lightcolor, ambientscale, diffusescale, specularscale); + R_Shadow_RenderLighting_Light_GLSL(texturenumsurfaces, texturesurfacelist, ambientcolor, diffusecolor, specularcolor); break; case R_SHADOW_RENDERMODE_LIGHT_VERTEX3DATTEN: case R_SHADOW_RENDERMODE_LIGHT_VERTEX2D1DATTEN: case R_SHADOW_RENDERMODE_LIGHT_VERTEX2DATTEN: case R_SHADOW_RENDERMODE_LIGHT_VERTEX: - R_Shadow_RenderLighting_Light_Vertex(texturenumsurfaces, texturesurfacelist, lightcolor, ambientscale, diffusescale); + R_Shadow_RenderLighting_Light_Vertex(texturenumsurfaces, texturesurfacelist, ambientcolor, diffusecolor); break; default: Con_Printf("R_Shadow_RenderLighting: unknown r_shadow_rendermode %i\n", r_shadow_rendermode); @@ -4459,7 +4459,7 @@ static void R_Shadow_DrawWorldShadow_ShadowMap(int numsurfaces, int *surfacelist { shadowmesh_t *mesh; - RSurf_ActiveWorldEntity(); + RSurf_ActiveModelEntity(r_refdef.scene.worldentity, false, false, false); if (rsurface.rtlight->compiled && r_shadow_realtime_world_compile.integer && r_shadow_realtime_world_compileshadow.integer) { @@ -4479,7 +4479,7 @@ static void R_Shadow_DrawWorldShadow_ShadowMap(int numsurfaces, int *surfacelist else if (r_refdef.scene.worldentity->model) r_refdef.scene.worldmodel->DrawShadowMap(r_shadow_shadowmapside, r_refdef.scene.worldentity, rsurface.rtlight->shadoworigin, NULL, rsurface.rtlight->radius, numsurfaces, surfacelist, surfacesides, rsurface.rtlight->cached_cullmins, rsurface.rtlight->cached_cullmaxs); - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity + rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity } static void R_Shadow_DrawWorldShadow_ShadowVolume(int numsurfaces, int *surfacelist, const unsigned char *trispvs) @@ -4494,7 +4494,7 @@ static void R_Shadow_DrawWorldShadow_ShadowVolume(int numsurfaces, int *surfacel if (r_refdef.scene.worldmodel->brush.shadowmesh ? !r_refdef.scene.worldmodel->brush.shadowmesh->neighbor3i : !r_refdef.scene.worldmodel->surfmesh.data_neighbor3i) return; - RSurf_ActiveWorldEntity(); + RSurf_ActiveModelEntity(r_refdef.scene.worldentity, false, false, false); if (rsurface.rtlight->compiled && r_shadow_realtime_world_compile.integer && r_shadow_realtime_world_compileshadow.integer) { @@ -4551,7 +4551,7 @@ static void R_Shadow_DrawWorldShadow_ShadowVolume(int numsurfaces, int *surfacel r_refdef.scene.worldmodel->DrawShadowVolume(r_refdef.scene.worldentity, rsurface.rtlight->shadoworigin, NULL, rsurface.rtlight->radius, numsurfaces, surfacelist, rsurface.rtlight->cached_cullmins, rsurface.rtlight->cached_cullmaxs); } - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity + rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity } static void R_Shadow_DrawEntityShadow(entity_render_t *ent) @@ -4577,7 +4577,7 @@ static void R_Shadow_DrawEntityShadow(entity_render_t *ent) ent->model->DrawShadowVolume(ent, relativeshadoworigin, NULL, relativeshadowradius, ent->model->nummodelsurfaces, ent->model->sortedmodelsurfaces, relativeshadowmins, relativeshadowmaxs); break; } - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity + rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity } void R_Shadow_SetupEntityLight(const entity_render_t *ent) @@ -4596,7 +4596,7 @@ static void R_Shadow_DrawWorldLight(int numsurfaces, int *surfacelist, const uns return; // set up properties for rendering light onto this entity - RSurf_ActiveWorldEntity(); + RSurf_ActiveModelEntity(r_refdef.scene.worldentity, false, false, false); rsurface.entitytolight = rsurface.rtlight->matrix_worldtolight; Matrix4x4_Concat(&rsurface.entitytoattenuationxyz, &matrix_attenuationxyz, &rsurface.entitytolight); Matrix4x4_Concat(&rsurface.entitytoattenuationz, &matrix_attenuationz, &rsurface.entitytolight); @@ -4604,7 +4604,7 @@ static void R_Shadow_DrawWorldLight(int numsurfaces, int *surfacelist, const uns r_refdef.scene.worldmodel->DrawLight(r_refdef.scene.worldentity, numsurfaces, surfacelist, lighttrispvs); - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity + rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity } static void R_Shadow_DrawEntityLight(entity_render_t *ent) @@ -4617,7 +4617,7 @@ static void R_Shadow_DrawEntityLight(entity_render_t *ent) model->DrawLight(ent, model->nummodelsurfaces, model->sortedmodelsurfaces, NULL); - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity + rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity } static void R_Shadow_PrepareLight(rtlight_t *rtlight) @@ -5567,7 +5567,7 @@ void R_Shadow_PrepareModelShadows(void) r_shadow_nummodelshadows = 0; r_shadow_shadowmapatlas_modelshadows_size = 0; - if (!r_refdef.scene.numentities || r_refdef.lightmapintensity <= 0.0f || r_shadows.integer <= 0) + if (!r_refdef.scene.numentities || r_refdef.scene.lightmapintensity <= 0.0f || r_shadows.integer <= 0) return; switch (r_shadow_shadowmode) @@ -5735,7 +5735,7 @@ static void R_Shadow_DrawModelShadowMaps(void) relativeshadowmaxs[2] = relativelightorigin[2] + r_shadows_throwdistance.value * fabs(relativelightdirection[2]) + radius * (fabs(relativeforward[2]) + fabs(relativeright[2])); RSurf_ActiveModelEntity(ent, false, false, false); ent->model->DrawShadowMap(0, ent, relativelightorigin, relativelightdirection, relativethrowdistance, ent->model->nummodelsurfaces, ent->model->sortedmodelsurfaces, NULL, relativeshadowmins, relativeshadowmaxs); - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity + rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity } #if 0 @@ -5832,45 +5832,14 @@ void R_Shadow_DrawModelShadows(void) Matrix4x4_Transform3x3(&ent->inversematrix, shadowdir, relativelightdirection); else { - if(ent->entitynumber != 0) - { - if(ent->entitynumber >= MAX_EDICTS) // csqc entity - { - // FIXME handle this - VectorNegate(ent->modellight_lightdir, relativelightdirection); - } - else - { - // networked entity - might be attached in some way (then we should use the parent's light direction, to not tear apart attached entities) - int entnum, entnum2, recursion; - entnum = entnum2 = ent->entitynumber; - for(recursion = 32; recursion > 0; --recursion) - { - entnum2 = cl.entities[entnum].state_current.tagentity; - if(entnum2 >= 1 && entnum2 < cl.num_entities && cl.entities_active[entnum2]) - entnum = entnum2; - else - break; - } - if(recursion && recursion != 32) // if we followed a valid non-empty attachment chain - { - VectorNegate(cl.entities[entnum].render.modellight_lightdir, relativelightdirection); - // transform into modelspace of OUR entity - Matrix4x4_Transform3x3(&cl.entities[entnum].render.matrix, relativelightdirection, tmp); - Matrix4x4_Transform3x3(&ent->inversematrix, tmp, relativelightdirection); - } - else - VectorNegate(ent->modellight_lightdir, relativelightdirection); - } - } - else - VectorNegate(ent->modellight_lightdir, relativelightdirection); + VectorNegate(ent->render_modellight_lightdir, tmp); + Matrix4x4_Transform3x3(&ent->inversematrix, tmp, relativelightdirection); } VectorScale(relativelightdirection, -relativethrowdistance, relativelightorigin); RSurf_ActiveModelEntity(ent, false, false, false); ent->model->DrawShadowVolume(ent, relativelightorigin, relativelightdirection, relativethrowdistance, ent->model->nummodelsurfaces, ent->model->sortedmodelsurfaces, relativeshadowmins, relativeshadowmaxs); - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity + rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity } // not really the right mode, but this will disable any silly stencil features @@ -6105,7 +6074,7 @@ void R_Shadow_DrawCoronas(void) qglGenQueriesARB(r_maxqueries - i, r_queries + i); CHECKGLERROR } - RSurf_ActiveWorldEntity(); + RSurf_ActiveModelEntity(r_refdef.scene.worldentity, false, false, false); GL_BlendFunc(GL_ONE, GL_ZERO); GL_CullFace(GL_NONE); GL_DepthMask(false); @@ -7569,141 +7538,48 @@ LIGHT SAMPLING ============================================================================= */ -void R_LightPoint(float *color, const vec3_t p, const int flags) +void R_CompleteLightPoint(float *ambient, float *diffuse, float *lightdir, const vec3_t p, const int flags, float lightmapintensity, float ambientintensity) { - int i, numlights, flag; - float f, relativepoint[3], dist, dist2, lightradius2; - vec3_t diffuse, n; - rtlight_t *light; - dlight_t *dlight; - - if (r_fullbright.integer) - { - VectorSet(color, 1, 1, 1); - return; - } - - VectorClear(color); - - if (flags & LP_LIGHTMAP) - { - if (!r_fullbright.integer && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->lit && r_refdef.scene.worldmodel->brush.LightPoint) - { - VectorClear(diffuse); - r_refdef.scene.worldmodel->brush.LightPoint(r_refdef.scene.worldmodel, p, color, diffuse, n); - VectorAdd(color, diffuse, color); - } - else - VectorSet(color, 1, 1, 1); - color[0] += r_refdef.scene.ambient; - color[1] += r_refdef.scene.ambient; - color[2] += r_refdef.scene.ambient; - } - - if (flags & LP_RTWORLD) - { - flag = r_refdef.scene.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE; - numlights = (int)Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); - for (i = 0; i < numlights; i++) - { - dlight = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, i); - if (!dlight) - continue; - light = &dlight->rtlight; - if (!(light->flags & flag)) - continue; - // sample - lightradius2 = light->radius * light->radius; - VectorSubtract(light->shadoworigin, p, relativepoint); - dist2 = VectorLength2(relativepoint); - if (dist2 >= lightradius2) - continue; - dist = sqrt(dist2) / light->radius; - f = dist < 1 ? (r_shadow_lightintensityscale.value * ((1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist))) : 0; - if (f <= 0) - continue; - // todo: add to both ambient and diffuse - if (!light->shadow || CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, 0, MATERIALFLAGMASK_TRANSLUCENT, collision_extendmovelength.value, true, false, NULL, false, true).fraction == 1) - VectorMA(color, f, light->currentcolor, color); - } - } - if (flags & LP_DYNLIGHT) - { - // sample dlights - for (i = 0;i < r_refdef.scene.numlights;i++) - { - light = r_refdef.scene.lights[i]; - // sample - lightradius2 = light->radius * light->radius; - VectorSubtract(light->shadoworigin, p, relativepoint); - dist2 = VectorLength2(relativepoint); - if (dist2 >= lightradius2) - continue; - dist = sqrt(dist2) / light->radius; - f = dist < 1 ? (r_shadow_lightintensityscale.value * ((1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist))) : 0; - if (f <= 0) - continue; - // todo: add to both ambient and diffuse - if (!light->shadow || CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, 0, MATERIALFLAGMASK_TRANSLUCENT, collision_extendmovelength.value, true, false, NULL, false, true).fraction == 1) - VectorMA(color, f, light->color, color); - } - } -} - -void R_CompleteLightPoint(vec3_t ambient, vec3_t diffuse, vec3_t lightdir, const vec3_t p, const int flags) -{ - int i, numlights, flag; + int i, numlights, flag, q; rtlight_t *light; dlight_t *dlight; float relativepoint[3]; float color[3]; - float dir[3]; float dist; float dist2; float intensity; - float sample[5*3]; + float sa[3], sx[3], sy[3], sz[3], sd[3]; float lightradius2; - if (r_fullbright.integer) - { - VectorSet(ambient, 1, 1, 1); - VectorClear(diffuse); - VectorClear(lightdir); - return; - } + // use first order spherical harmonics to combine directional lights + for (q = 0; q < 3; q++) + sa[q] = sx[q] = sy[q] = sz[q] = sd[q] = 0; - if (flags == LP_LIGHTMAP) + if (flags & LP_LIGHTMAP) { - VectorSet(ambient, r_refdef.scene.ambient, r_refdef.scene.ambient, r_refdef.scene.ambient); - VectorClear(diffuse); - VectorClear(lightdir); if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->lit && r_refdef.scene.worldmodel->brush.LightPoint) - r_refdef.scene.worldmodel->brush.LightPoint(r_refdef.scene.worldmodel, p, ambient, diffuse, lightdir); + { + float tempambient[3]; + for (q = 0; q < 3; q++) + tempambient[q] = color[q] = relativepoint[q] = 0; + r_refdef.scene.worldmodel->brush.LightPoint(r_refdef.scene.worldmodel, p, tempambient, color, relativepoint); + // calculate a weighted average light direction as well + intensity = VectorLength(color); + for (q = 0; q < 3; q++) + { + sa[q] += (0.5f * color[q] + tempambient[q]) * lightmapintensity; + sx[q] += (relativepoint[0] * color[q]) * lightmapintensity; + sy[q] += (relativepoint[1] * color[q]) * lightmapintensity; + sz[q] += (relativepoint[2] * color[q]) * lightmapintensity; + sd[q] += (intensity * relativepoint[q]) * lightmapintensity; + } + } else - VectorSet(ambient, 1, 1, 1); - return; - } - - memset(sample, 0, sizeof(sample)); - VectorSet(sample, r_refdef.scene.ambient, r_refdef.scene.ambient, r_refdef.scene.ambient); - - if ((flags & LP_LIGHTMAP) && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->lit && r_refdef.scene.worldmodel->brush.LightPoint) - { - vec3_t tempambient; - VectorClear(tempambient); - VectorClear(color); - VectorClear(relativepoint); - r_refdef.scene.worldmodel->brush.LightPoint(r_refdef.scene.worldmodel, p, tempambient, color, relativepoint); - VectorScale(tempambient, r_refdef.lightmapintensity, tempambient); - VectorScale(color, r_refdef.lightmapintensity, color); - VectorAdd(sample, tempambient, sample); - VectorMA(sample , 0.5f , color, sample ); - VectorMA(sample + 3, relativepoint[0], color, sample + 3); - VectorMA(sample + 6, relativepoint[1], color, sample + 6); - VectorMA(sample + 9, relativepoint[2], color, sample + 9); - // calculate a weighted average light direction as well - intensity = VectorLength(color); - VectorMA(sample + 12, intensity, relativepoint, sample + 12); + { + // unlit map - fullbright but scaled by lightmapintensity + for (q = 0; q < 3; q++) + sa[q] += lightmapintensity; + } } if (flags & LP_RTWORLD) @@ -7730,17 +7606,18 @@ void R_CompleteLightPoint(vec3_t ambient, vec3_t diffuse, vec3_t lightdir, const continue; if (light->shadow && CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, 0, MATERIALFLAGMASK_TRANSLUCENT, collision_extendmovelength.value, true, false, NULL, false, true).fraction < 1) continue; - // scale down intensity to add to both ambient and diffuse - //intensity *= 0.5f; + for (q = 0; q < 3; q++) + color[q] = light->currentcolor[q] * intensity; + intensity = VectorLength(color); VectorNormalize(relativepoint); - VectorScale(light->currentcolor, intensity, color); - VectorMA(sample , 0.5f , color, sample ); - VectorMA(sample + 3, relativepoint[0], color, sample + 3); - VectorMA(sample + 6, relativepoint[1], color, sample + 6); - VectorMA(sample + 9, relativepoint[2], color, sample + 9); - // calculate a weighted average light direction as well - intensity *= VectorLength(color); - VectorMA(sample + 12, intensity, relativepoint, sample + 12); + for (q = 0; q < 3; q++) + { + sa[q] += 0.5f * color[q]; + sx[q] += relativepoint[0] * color[q]; + sy[q] += relativepoint[1] * color[q]; + sz[q] += relativepoint[2] * color[q]; + sd[q] += intensity * relativepoint[q]; + } } // FIXME: sample bouncegrid too! } @@ -7763,30 +7640,30 @@ void R_CompleteLightPoint(vec3_t ambient, vec3_t diffuse, vec3_t lightdir, const continue; if (light->shadow && CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, 0, MATERIALFLAGMASK_TRANSLUCENT, collision_extendmovelength.value, true, false, NULL, false, true).fraction < 1) continue; - // scale down intensity to add to both ambient and diffuse - //intensity *= 0.5f; + for (q = 0; q < 3; q++) + color[q] = light->currentcolor[q] * intensity; + intensity = VectorLength(color); VectorNormalize(relativepoint); - VectorScale(light->currentcolor, intensity, color); - VectorMA(sample , 0.5f , color, sample ); - VectorMA(sample + 3, relativepoint[0], color, sample + 3); - VectorMA(sample + 6, relativepoint[1], color, sample + 6); - VectorMA(sample + 9, relativepoint[2], color, sample + 9); - // calculate a weighted average light direction as well - intensity *= VectorLength(color); - VectorMA(sample + 12, intensity, relativepoint, sample + 12); + for (q = 0; q < 3; q++) + { + sa[q] += 0.5f * color[q]; + sx[q] += relativepoint[0] * color[q]; + sy[q] += relativepoint[1] * color[q]; + sz[q] += relativepoint[2] * color[q]; + sd[q] += intensity * relativepoint[q]; + } } } - // calculate the direction we'll use to reduce the sample to a directional light source - VectorCopy(sample + 12, dir); - //VectorSet(dir, sample[3] + sample[4] + sample[5], sample[6] + sample[7] + sample[8], sample[9] + sample[10] + sample[11]); - VectorNormalize(dir); - // extract the diffuse color along the chosen direction and scale it - diffuse[0] = (dir[0]*sample[3] + dir[1]*sample[6] + dir[2]*sample[ 9] + sample[ 0]); - diffuse[1] = (dir[0]*sample[4] + dir[1]*sample[7] + dir[2]*sample[10] + sample[ 1]); - diffuse[2] = (dir[0]*sample[5] + dir[1]*sample[8] + dir[2]*sample[11] + sample[ 2]); - // subtract some of diffuse from ambient - VectorMA(sample, -0.333f, diffuse, ambient); - // store the normalized lightdir - VectorCopy(dir, lightdir); + // calculate the weighted-average light direction (bentnormal) + for (q = 0; q < 3; q++) + lightdir[q] = sd[q]; + VectorNormalize(lightdir); + for (q = 0; q < 3; q++) + { + // extract the diffuse color along the chosen direction and scale it + diffuse[q] = (lightdir[0] * sx[q] + lightdir[1] * sy[q] + lightdir[2] * sz[q]); + // subtract some of diffuse from ambient + ambient[q] = sa[q] + -0.333f * diffuse[q] + ambientintensity; + } } diff --git a/r_shadow.h b/r_shadow.h index 3346b77e..809805eb 100644 --- a/r_shadow.h +++ b/r_shadow.h @@ -159,8 +159,7 @@ void R_Shadow_PrepareModelShadows(void); #define LP_LIGHTMAP 1 #define LP_RTWORLD 2 #define LP_DYNLIGHT 4 -void R_LightPoint(float *color, const vec3_t p, const int flags); -void R_CompleteLightPoint(float *ambientcolor, float *diffusecolor, float *diffusenormal, const vec3_t p, const int flags); +void R_CompleteLightPoint(float *ambient, float *diffuse, float *lightdir, const vec3_t p, const int flags, float lightmapintensity, float ambientintensity); void R_Shadow_DrawShadowMaps(void); void R_Shadow_DrawModelShadows(void); diff --git a/r_sprites.c b/r_sprites.c index a45a3e73..d72bee10 100644 --- a/r_sprites.c +++ b/r_sprites.c @@ -392,9 +392,15 @@ static void R_Model_Sprite_Draw_TransparentCallback(const entity_render_t *ent, frame = model->sprite.sprdata_frames + ent->frameblend[i].subframe; texture = R_GetCurrentTexture(model->data_textures + ent->frameblend[i].subframe); - // lit sprite by lightgrid if it is not fullbright, lit only ambient + // sprites are fullbright by default, but if this one is not fullbright we + // need to combine the lighting into ambient as sprite lighting is not + // directional if (!(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) - VectorAdd(ent->modellight_ambient, ent->modellight_diffuse, rsurface.modellight_ambient); // sprites dont use lightdirection + { + VectorMAM(1.0f, texture->render_modellight_ambient, 0.25f, texture->render_modellight_diffuse, texture->render_modellight_ambient); + VectorClear(texture->render_modellight_diffuse); + VectorClear(texture->render_modellight_specular); + } // SPR_LABEL should not use depth test AT ALL if(model->sprite.sprnum_type == SPR_LABEL || model->sprite.sprnum_type == SPR_LABEL_SCALE) diff --git a/render.h b/render.h index 7fcadb3b..32a607f3 100644 --- a/render.h +++ b/render.h @@ -125,7 +125,7 @@ extern cvar_t r_dynamic; void R_Init(void); void R_UpdateVariables(void); // must call after setting up most of r_refdef, but before calling R_RenderView -void R_RenderView(void); // must set r_refdef and call R_UpdateVariables first +void R_RenderView(void); // must set r_refdef and call R_UpdateVariables and CL_UpdateEntityShading first void R_RenderView_UpdateViewVectors(void); // just updates r_refdef.view.{forward,left,up,origin,right,inverse_matrix} typedef enum r_refdef_scene_type_s { @@ -401,18 +401,6 @@ typedef struct rsurfacestate_s // animation blending state from entity frameblend_t frameblend[MAX_FRAMEBLENDS]; skeleton_t *skeleton; - // directional model shading state from entity - vec3_t modellight_ambient; - vec3_t modellight_diffuse; - vec3_t modellight_lightdir; - // colormapping state from entity (these are black if colormapping is off) - vec3_t colormap_pantscolor; - vec3_t colormap_shirtcolor; - // special coloring of ambient/diffuse textures (gloss not affected) - // colormod[3] is the alpha of the entity - float colormod[4]; - // special coloring of glow textures - float glowmod[3]; // view location in model space vec3_t localvieworigin; // polygon offset data for submodels @@ -451,8 +439,8 @@ typedef struct rsurfacestate_s float userwavefunc_param[Q3WAVEFUNC_USER_COUNT]; // pointer to an entity_render_t used only by R_GetCurrentTexture and - // RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity as a unique id within - // each frame (see r_frame also) + // RSurf_ActiveModelEntity as a unique id within each frame (see r_frame + // also) entity_render_t *entity; } rsurfacestate_t; @@ -461,7 +449,6 @@ extern rsurfacestate_t rsurface; void R_HDR_UpdateIrisAdaptation(const vec3_t point); -void RSurf_ActiveWorldEntity(void); void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, qboolean wanttangents, qboolean prepass); void RSurf_ActiveCustomEntity(const matrix4x4_t *matrix, const matrix4x4_t *inversematrix, int entflags, double shadertime, float r, float g, float b, float a, int numvertices, const float *vertex3f, const float *texcoord2f, const float *normal3f, const float *svector3f, const float *tvector3f, const float *color4f, int numtriangles, const int *element3i, const unsigned short *element3s, qboolean wantnormals, qboolean wanttangents); void RSurf_SetupDepthAndCulling(void); @@ -508,7 +495,7 @@ rsurfacepass_t; void R_SetupShader_Generic(rtexture_t *first, rtexture_t *second, int texturemode, int rgbscale, qboolean usegamma, qboolean notrippy, qboolean suppresstexalpha); void R_SetupShader_Generic_NoTexture(qboolean usegamma, qboolean notrippy); void R_SetupShader_DepthOrShadow(qboolean notrippy, qboolean depthrgb, qboolean skeletal); -void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, float ambientscale, float diffusescale, float specularscale, rsurfacepass_t rsurfacepass, int texturenumsurfaces, const msurface_t **texturesurfacelist, void *waterplane, qboolean notrippy); +void R_SetupShader_Surface(const float ambientcolor[3], const float diffusecolor[3], const float specularcolor[3], rsurfacepass_t rsurfacepass, int texturenumsurfaces, const msurface_t **texturesurfacelist, void *waterplane, qboolean notrippy); void R_SetupShader_DeferredLight(const rtlight_t *rtlight); typedef struct r_waterstate_waterplane_s diff --git a/shader_glsl.h b/shader_glsl.h index a69dbbc5..36542c53 100644 --- a/shader_glsl.h +++ b/shader_glsl.h @@ -1421,12 +1421,6 @@ "uniform sampler2D Texture_ReflectMask;\n", "uniform samplerCube Texture_ReflectCube;\n", "#endif\n", -"#ifdef MODE_LIGHTDIRECTION\n", -"uniform myhalf3 LightColor;\n", -"#endif\n", -"#ifdef MODE_LIGHTSOURCE\n", -"uniform myhalf3 LightColor;\n", -"#endif\n", "#ifdef USEBOUNCEGRID\n", "uniform sampler3D Texture_BounceGrid;\n", "uniform float BounceGridIntensity;\n", @@ -1528,7 +1522,6 @@ "#else\n", " color.rgb = diffusetex * Color_Ambient;\n", "#endif\n", -" color.rgb *= LightColor;\n", " color.rgb *= cast_myhalf(dp_texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0)));\n", "#if defined(USESHADOWMAP2D)\n", " color.rgb *= ShadowMapCompare(CubeVector);\n", @@ -1546,7 +1539,7 @@ " #ifdef USEDIFFUSE\n", " myhalf3 lightnormal = cast_myhalf3(normalize(LightVector));\n", " #endif\n", -" #define lightcolor LightColor\n", +" #define lightcolor 1\n", "#endif // MODE_LIGHTDIRECTION\n", "#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " #define SHADING\n", @@ -1589,7 +1582,7 @@ "#ifdef MODE_FAKELIGHT\n", " #define SHADING\n", " myhalf3 lightnormal = cast_myhalf3(normalize(EyeVectorFogDepth.xyz));\n", -" myhalf3 lightcolor = cast_myhalf3(1.0);\n", +" #define lightcolor 1\n", "#endif // MODE_FAKELIGHT\n", "\n", "\n", diff --git a/shader_hlsl.h b/shader_hlsl.h index 9b3f04c3..57df52d0 100644 --- a/shader_hlsl.h +++ b/shader_hlsl.h @@ -1329,12 +1329,6 @@ "uniform sampler Texture_ReflectMask : register(s5),\n", "uniform samplerCUBE Texture_ReflectCube : register(s6),\n", "#endif\n", -"#ifdef MODE_LIGHTDIRECTION\n", -"uniform half3 LightColor : register(c21),\n", -"#endif\n", -"#ifdef MODE_LIGHTSOURCE\n", -"uniform half3 LightColor : register(c21),\n", -"#endif\n", "\n", "#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE)\n", "uniform sampler Texture_Attenuation : register(s9),\n", @@ -1451,7 +1445,6 @@ "#else\n", " color.rgb = diffusetex * Color_Ambient;\n", "#endif\n", -" color.rgb *= LightColor;\n", " color.rgb *= half(tex2D(Texture_Attenuation, float2(length(CubeVector), 0.0)).r);\n", "#if defined(USESHADOWMAP2D)\n", " color.rgb *= half(ShadowMapCompare(CubeVector, Texture_ShadowMap2D, ShadowMap_Parameters, ShadowMap_TextureScale\n", @@ -1497,7 +1490,7 @@ " #ifdef USEDIFFUSE\n", " half3 lightnormal = half3(normalize(LightVector));\n", " #endif\n", -" #define lightcolor LightColor\n", +" #define lightcolor 1\n", "#endif // MODE_LIGHTDIRECTION\n", "#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " #define SHADING\n", @@ -1536,7 +1529,7 @@ "#ifdef MODE_FAKELIGHT\n", " #define SHADING\n", " half3 lightnormal = half3(normalize(EyeVector));\n", -" half3 lightcolor = half3(1.0,1.0,1.0);\n", +" #define lightcolor 1\n", "#endif // MODE_FAKELIGHT\n", "\n", "\n",