From 86e427126c7e9fb37d1a3e5c326fc58b1cc1b8c0 Mon Sep 17 00:00:00 2001 From: Shpoike Date: Wed, 19 May 2021 04:40:38 +0100 Subject: [PATCH] First attempt at hl2 lightcube stuff. --- engine/client/cl_ents.c | 6 +- engine/client/clq2_ents.c | 4 +- engine/client/console.c | 2 +- engine/client/m_options.c | 2 +- engine/client/pr_csqc.c | 4 +- engine/client/r_part.c | 4 +- engine/client/render.h | 10 +- engine/client/screen.h | 2 +- engine/common/com_mesh.c | 3 +- engine/common/gl_q2bsp.c | 246 ++++++++++++++++++++++--- engine/gl/gl_alias.c | 33 ++-- engine/gl/gl_backend.c | 44 ++++- engine/gl/gl_heightmap.c | 3 +- engine/gl/gl_model.h | 4 +- engine/gl/gl_rlight.c | 17 +- engine/gl/gl_shader.c | 4 +- engine/gl/gl_vidcommon.c | 8 +- engine/gl/glquake.h | 2 +- engine/gl/shader.h | 4 + engine/server/pr_cmds.c | 4 +- engine/server/sv_user.c | 4 +- engine/shaders/glsl/vmt_refract.glsl | 2 +- engine/shaders/glsl/vmt_vertexlit.glsl | 16 +- 23 files changed, 337 insertions(+), 91 deletions(-) diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 9478ca3e..e437dca5 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -3439,14 +3439,14 @@ void CL_LinkStaticEntities(void *pvs, int *areas) Mod_LoadModel(src->model, MLV_WARN); //we use threads, so these'll load in time. continue; } - if (!src->light_known) + /*if (!src->light_known) { vec3_t tmp; VectorCopy(src->origin, tmp); VectorCopy(sent->lightorg, src->origin); R_CalcModelLighting(src, src->model); //bake and cache, now everything else is working. VectorCopy(tmp, src->origin); - } + }*/ if (src->pvscache.num_leafs==-2) { vec3_t absmin, absmax; @@ -4072,7 +4072,7 @@ void CL_LinkPacketEntities (void) #ifdef HEXEN2 ent->h2playerclass = 0; #endif - ent->light_known = 0; + ent->light_type = ELT_UNKNOWN; ent->forcedshader = NULL; ent->shaderTime = 0; diff --git a/engine/client/clq2_ents.c b/engine/client/clq2_ents.c index f250c103..75bb0c39 100644 --- a/engine/client/clq2_ents.c +++ b/engine/client/clq2_ents.c @@ -2062,7 +2062,7 @@ static void CLQ2_AddPacketEntities (q2frame_t *frame) ent.shaderRGBAf[1] = 0; ent.shaderRGBAf[2] = 0; //bypasses world lighting - ent.light_known = true; + ent.light_type = ELT_LAMBERT; VectorSet(ent.light_avg, 1, 1, 1); VectorSet(ent.light_range, 0, 0, 0); //(yes, its a bit shit. not even a post-process thing) @@ -2070,7 +2070,7 @@ static void CLQ2_AddPacketEntities (q2frame_t *frame) // add to refresh list V_AddEntity (&ent); - ent.light_known = false; + ent.light_type = ELT_UNKNOWN; ent.customskin = 0; diff --git a/engine/client/console.c b/engine/client/console.c index 323a4bce..9963c5cb 100644 --- a/engine/client/console.c +++ b/engine/client/console.c @@ -2808,7 +2808,7 @@ static void Con_DrawModelPreview(model_t *model, float x, float y, float w, floa ent.light_dir[1] = DotProduct(lightpos, ent.axis[1]); ent.light_dir[2] = DotProduct(lightpos, ent.axis[2]); - ent.light_known = 2; + ent.light_type = ELT_FLAT; V_AddEntity(&ent); diff --git a/engine/client/m_options.c b/engine/client/m_options.c index d7a6a112..2aeb8480 100644 --- a/engine/client/m_options.c +++ b/engine/client/m_options.c @@ -3535,7 +3535,7 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct emenu ent.light_dir[1] = DotProduct(lightpos, ent.axis[1]); ent.light_dir[2] = DotProduct(lightpos, ent.axis[2]); - ent.light_known = 2; + ent.light_type = ELT_FLAT; if (ent.model->type == mod_dummy) { diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index e7d973f1..d6ca4258 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -5437,13 +5437,13 @@ static void QCBUILTIN PF_cs_droptofloor (pubprogfuncs_t *prinst, struct globalva static void QCBUILTIN PF_cl_getlight (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { - vec3_t ambient, diffuse, dir; + vec3_t ambient, diffuse, dir, cube[6]; if (csqc_world.worldmodel->lightmaps.maxstyle >= cl_max_lightstyles || !csqc_world.worldmodel || csqc_world.worldmodel->loadstate != MLS_LOADED || !csqc_world.worldmodel->funcs.LightPointValues) VectorSet(G_VECTOR(OFS_RETURN), 0, 0, 0); else { - csqc_world.worldmodel->funcs.LightPointValues(csqc_world.worldmodel, G_VECTOR(OFS_PARM0), ambient, diffuse, dir); + csqc_world.worldmodel->funcs.LightPointValues(csqc_world.worldmodel, G_VECTOR(OFS_PARM0), ambient, diffuse, dir, cube); VectorMA(ambient, 0.5, diffuse, G_VECTOR(OFS_RETURN)); } } diff --git a/engine/client/r_part.c b/engine/client/r_part.c index 21756e90..e32117aa 100644 --- a/engine/client/r_part.c +++ b/engine/client/r_part.c @@ -93,7 +93,7 @@ float R_Clutter_FRandom(clutter_build_ctx_t *ctx) static void R_Clutter_Insert_Soup(clutter_build_ctx_t *ctx, shader_t *shader, vecV_t *fte_restrict coord, vec2_t *fte_restrict texcoord, vec3_t *fte_restrict normal, vec3_t *fte_restrict sdir, vec3_t *fte_restrict tdir, vec4_t *fte_restrict colours, size_t numverts, index_t *fte_restrict index, size_t numidx, float scale, vec3_t origin, vec3_t axis[]) { - vec3_t diffuse, ambient, ldir; + vec3_t diffuse, ambient, ldir, cube[6]; float dot; struct clutter_build_ctx_soup_s *soup = NULL; size_t i; @@ -141,7 +141,7 @@ static void R_Clutter_Insert_Soup(clutter_build_ctx_t *ctx, shader_t *shader, ve soup->idx[soup->numidx++] = soup->numverts+*index++; - cl.worldmodel->funcs.LightPointValues(cl.worldmodel, origin, diffuse, ambient, ldir); + cl.worldmodel->funcs.LightPointValues(cl.worldmodel, origin, diffuse, ambient, ldir, cube); VectorScale(ambient, 1/255.0, ambient); VectorScale(diffuse, 1/255.0, diffuse); diff --git a/engine/client/render.h b/engine/client/render.h index 29e22b4a..44b72fd2 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -87,6 +87,13 @@ typedef enum { RT_MAX_REF_ENTITY_TYPE } refEntityType_t; +enum entlighttype_e +{ + ELT_UNKNOWN, //not computed yet. + ELT_LAMBERT, + ELT_FLAT, + ELT_CUBE, +}; typedef unsigned int skinid_t; //skin 0 is 'unused' @@ -105,7 +112,8 @@ typedef struct entity_s float shaderTime; /*timestamp, for syncing shader times to spawns*/ vec3_t glowmod; /*meant to be a multiplier for the fullbrights*/ - int light_known; /*bsp lighting has been calced*/ + enum entlighttype_e light_type; /*bsp lighting has been calced*/ + vec3_t light_cube[6]; /*hl2-style lighting*/ vec3_t light_avg; /*midpoint level*/ vec3_t light_range; /*avg + this = max, avg - this = min*/ vec3_t light_dir; diff --git a/engine/client/screen.h b/engine/client/screen.h index 89ee9cf4..d77099b9 100644 --- a/engine/client/screen.h +++ b/engine/client/screen.h @@ -107,7 +107,7 @@ typedef enum uploadfmt PTI_L8_SRGB, //8bit format. luminance gets flooded to all RGB channels. might be supported using swizzles. PTI_L8A8_SRGB, //16bit format. L=luminance. note: this cannot be implemented as a swizzle as there's no way to get srgb on red without it on green. //small formats. - PTI_P8, //used for paletted data. Loaded as R8, but separate purely due to mipmap generation. should probably make a mipgen enum. + PTI_P8, //used for paletted data (with common/engine palette). Loaded as R8, but separate purely due to mipmap generation. should probably make a mipgen enum. PTI_R8, //used for greyscale data (that doesn't need to get expanded to rgb). PTI_RG8, //might be useful for normalmaps PTI_R8_SNORM, diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index 1dbeb666..62585295 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -2736,11 +2736,12 @@ qboolean Mod_Mesh_EdictInFatPVS(struct model_s *model, const struct pvscache_s * void Mod_Mesh_FindTouchedLeafs(struct model_s *model, struct pvscache_s *ent, const vec3_t cullmins, const vec3_t cullmaxs) { } -static void Mod_Mesh_LightPointValues(struct model_s *model, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir) +static enum entlighttype_e Mod_Mesh_LightPointValues(struct model_s *model, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir, vec3_t res_cube[6]) { //trisoup doesn't have any actual pvs, thus we can't report anything... VectorSet(res_diffuse, 255,255,255); VectorSet(res_ambient, 128,128,128); VectorSet(res_dir, 0,0,1); + return ELT_LAMBERT; } static void Mod_SetMeshModelFuncs(model_t *mod, qboolean isstatic) { diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index 9668c6d6..bddd8855 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -44,6 +44,7 @@ cvar_t q3bsp_bihtraces = CVARFD("_q3bsp_bihtraces", /*FIXME: generate BIH leafs #ifdef HL2BSPS static cvar_t hl2_displacement_scale = CVARFD("hl2_displacement_scale", "1", CVAR_RENDERERLATCH|CVAR_CHEAT, "Multiplier for how far displacements can move."); +static cvar_t hl2_favour_ldr = CVARFD("hl2_favour_ldr", "0", CVAR_RENDERERLATCH|CVAR_CHEAT, "Favour LDR data instead of HDR (when both are present)."); #endif #if Q3SURF_NODRAW != TI_NODRAW @@ -324,6 +325,16 @@ typedef struct cminfo_s qbyte portalquerying[MAX_Q2MAP_AREAPORTALS]; mesh_t *portalpoly; //[numq2areaportals] int *occlusionqueries; //[numq2areaportals] + + struct mleaflight_s + { + struct leaflightpoint_s + { + vec3_t rgb[6]; + qbyte x, y, z; + } *point; + int count; + } *leaflight; #endif @@ -4498,8 +4509,8 @@ enum hllumps_e VLUMP_VISIBILITY = LUMP_VISIBILITY, VLUMP_NODES = LUMP_NODES, VLUMP_TEXINFO = LUMP_TEXINFO, - VLUMP_FACES = LUMP_FACES, - VLUMP_LIGHTING = LUMP_LIGHTING, + VLUMP_FACES_LDR = LUMP_FACES, + VLUMP_LIGHTING_LDR = LUMP_LIGHTING, // VLUMP_FOO = 9,//LUMP_CLIPNODES VLUMP_LEAFS = LUMP_LEAFS, // VLUMP_FOO = 11,//LUMP_MARKSURFACES @@ -4543,14 +4554,14 @@ enum hllumps_e VLUMP_DISP_TRIFLAGS = 48, // VLUMP_FOO = 49, // VLUMP_FOO = 50, -// VLUMP_FOO = 51, -// VLUMP_FOO = 52, + VLUMP_LEAFLIGHTI_HDR= 51, //indexes into VLUMP_LEAFLIGHTV_HDR, two shorts per leaf. + VLUMP_LEAFLIGHTI_LDR= 52, VLUMP_LIGHTING_HDR = 53, // VLUMP_FOO = 54, -// VLUMP_FOO = 55, -// VLUMP_FOO = 56, + VLUMP_LEAFLIGHTV_HDR= 55, + VLUMP_LEAFLIGHTV_LDR= 56, // VLUMP_FOO = 57, -// VLUMP_FOO = 58, + VLUMP_FACES_HDR = 58, // VLUMP_FOO = 59, // VLUMP_FOO = 60, // VLUMP_FOO = 61, @@ -4821,6 +4832,11 @@ typedef struct //new for hl2 short leafwaterid; + struct //present in v19. gone in v20. + { + qbyte rgb[3]; + signed char e; + } light[6]; short pad; } hl2dleaf_t; static qboolean CModHL2_LoadLeafs (model_t *mod, qbyte *mod_base, lump_t *l, int ver) @@ -4831,7 +4847,8 @@ static qboolean CModHL2_LoadLeafs (model_t *mod, qbyte *mod_base, lump_t *l, int hl2dleaf_t *in; int count; size_t insize = sizeof(*in); - if (ver == 19) + struct leaflightpoint_s *lightpoint = NULL; + if (ver < 20) insize = 56; //older maps have some lighting info here. else insize = 32; @@ -4862,6 +4879,12 @@ static qboolean CModHL2_LoadLeafs (model_t *mod, qbyte *mod_base, lump_t *l, int mod->leafs = out; mod->numleafs = count; + if (ver < 20) + { + prv->leaflight = ZG_Malloc(&mod->memgroup, sizeof(*out) * count); + lightpoint = ZG_Malloc(&mod->memgroup, sizeof(*lightpoint) * count); + } + for ( i=0 ; icluster >= mod->numclusters) mod->numclusters = out->cluster + 1; + + if (lightpoint) + { + for (j = 0; j < 6; j++) + { + float e = pow(2, in->light[j].e); + lightpoint->rgb[j][0] = e * in->light[j].rgb[0]; + lightpoint->rgb[j][1] = e * in->light[j].rgb[1]; + lightpoint->rgb[j][2] = e * in->light[j].rgb[2]; + } + prv->leaflight[i].count = 1; + prv->leaflight[i].point = lightpoint++; + } } - out = mod->leafs; mod->pvsbytes = ((mod->numclusters + 31)>>3)&~3; return true; } +#ifdef HAVE_CLIENT +static void CModHL2_LoadLeafLight (model_t *mod, qbyte *mod_base, lump_t *hdridx, lump_t *ldridx, lump_t *hdrvals, lump_t *ldrvals, int version) +{ + cminfo_t *prv = (cminfo_t*)mod->meshinfo; + lump_t *lump_idx, *lump_vals; + struct leaflightpoint_s *point; + size_t i, j; + unsigned short *in; + qbyte *inpoint; + + if (version < 20) + return; //nope. this info is in the leafs. + + if (hdridx && hdrvals) + lump_idx = hdridx, lump_vals = hdrvals; + else if (ldridx && ldrvals) + lump_idx = ldridx, lump_vals = ldrvals; + else + return; //unsupported. + + if (lump_vals->filelen%(7*4)) + return; + + if (lump_idx->filelen != mod->numleafs*sizeof(short)*2) + return; //erk? + + //easy enough to load some of the data... + point = ZG_Malloc(&mod->memgroup, sizeof(*point)*(lump_vals->filelen/(7*4))); + inpoint = mod_base + lump_vals->fileofs; + for (i = 0; i < lump_vals->filelen/(7*4); i++) + { + for (j = 0; j < 6; j++, inpoint+=4) + { + float e = pow(2, (signed char)inpoint[3]); + point[i].rgb[j][0] = e * inpoint[0]; + point[i].rgb[j][1] = e * inpoint[1]; + point[i].rgb[j][2] = e * inpoint[2]; + } + point[i].x = *inpoint++; + point[i].y = *inpoint++; + point[i].z = *inpoint++; + inpoint++; + } + + prv->leaflight = ZG_Malloc(&mod->memgroup, sizeof(*prv->leaflight)*mod->numleafs); + in = (unsigned short*)(mod_base + lump_idx->fileofs); + for (i = 0; i < mod->numleafs; i++) + { + prv->leaflight[i].count = LittleShort(*in++); + prv->leaflight[i].point = point + (unsigned short)LittleShort(*in++); + } +} +enum entlighttype_e HL2BSP_LightPointValues (struct model_s *model, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir, vec3_t res_cube[6]) +{ + cvar_t *srgbmag = Cvar_Get("lt_srgb_mag", "1", 0, "TEST"); + cvar_t *scale = Cvar_Get("lt_scale", "256", 0, "TEST"); + cvar_t *forceface = Cvar_Get("lt_face", "-1", 0, "TEST"); + + cminfo_t *prv = (cminfo_t*)model->meshinfo; + int leafnum = CM_PointLeafnum(model,point); + mleaf_t *leaf = model->leafs+leafnum; + struct mleaflight_s *leaflight = prv->leaflight+leafnum; + struct leaflightpoint_s *best, *lp; + size_t i, j, d, bd=~0; + int xyz[3]; + vec3_t diff[6]; + float sig[6]; + + if (prv->leaflight && leaflight->count) + { + for (i = 0; i < 3; i++) + xyz[i] = 255*(point[i] - leaf->minmaxs[i]) / (leaf->minmaxs[3+i]-leaf->minmaxs[i]); + for (i = 0, best=lp = leaflight->point; i < leaflight->count; i++, lp++) + { + int m[3]; + m[0] = xyz[0] - lp->x; + m[1] = xyz[1] - lp->y; + m[2] = xyz[2] - lp->z; + d = DotProduct(m,m); + if (bd > d) + { + bd = d; + best = lp; + } + } + + + VectorClear(res_ambient); + for (j = 0; j < 6; j++) + VectorAdd(res_ambient, best->rgb[j], res_ambient); + VectorScale(res_ambient, 1.0/6, res_ambient); + + //try and figure out an average dir for the brightest direction + for (j = 0; j < 6; j++) + { + VectorSubtract(best->rgb[j], res_ambient, diff[j]); + sig[j] = VectorLength(diff[j]); + } + for (j = 0; j < 3; j++) + res_dir[j] = sig[j*2+1] - sig[j*2]; + VectorNormalize(res_dir); + + //figure out how much light there should be in that direction. + VectorCopy(res_ambient, res_diffuse); + for (j = 0; j < 3; j++) + { + if (res_dir[0]>=0) + VectorMA(res_diffuse, res_dir[0], diff[j*2+1], res_diffuse); + else + VectorMA(res_diffuse, -res_dir[0], diff[j*2+0], res_diffuse); + } + + if (forceface->ival >= 0) + { + VectorCopy(best->rgb[forceface->ival], res_diffuse); + VectorCopy(best->rgb[forceface->ival], res_ambient); + VectorClear(res_dir); + res_dir[forceface->ival/3] = (forceface->ival&1)?-1:1; + } + + if (srgbmag->value) + { + for (j = 0; j < 3; j++) + { + res_diffuse[j] = M_LinearToSRGB(res_diffuse[j], srgbmag->value)*scale->value; + res_ambient[j] = M_LinearToSRGB(res_ambient[j], srgbmag->value)*scale->value; + } + + for (j = 0; j < 6; j++) + { + res_cube[j][0] = M_LinearToSRGB(best->rgb[j][0], srgbmag->value)*scale->value; + res_cube[j][1] = M_LinearToSRGB(best->rgb[j][1], srgbmag->value)*scale->value; + res_cube[j][2] = M_LinearToSRGB(best->rgb[j][2], srgbmag->value)*scale->value; + } + } + else + { + VectorScale(res_diffuse, scale->value, res_diffuse); + VectorScale(res_ambient, scale->value, res_ambient); + + for (j = 0; j < 6; j++) + VectorScale(best->rgb[j], scale->value, res_cube[j]); + } + + return ELT_CUBE; + } + VectorSet(res_dir, 0,0.707,0.707); + VectorSet(res_diffuse, 64,64,64); + VectorSet(res_ambient, 192,192,192); + return ELT_FLAT; +} +#endif + #if defined(HAVE_CLIENT) && defined(GLQUAKE) //for each area that we recurse, follow the neighbouring areas and check their area portals too. //if a portal is closed, we switch to using a solid opaque shader, to avoid any HOM glitches. @@ -5308,8 +5496,8 @@ typedef struct } hl2dface_t; static qboolean CModHL2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *lumps, int version) { - lump_t *l = &lumps[VLUMP_FACES]; - lump_t *l2 = &lumps[58]; + lump_t *l = &lumps[VLUMP_FACES_LDR]; + lump_t *l2 = &lumps[VLUMP_FACES_HDR]; hl2dface_t *in; msurface_t *out; int i, count, surfnum; @@ -5317,7 +5505,7 @@ static qboolean CModHL2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *lumps, int ti, st; int lumpsize = sizeof(*in); - if (l2->filelen) + if (l2->filelen && !(hl2_favour_ldr.ival && lumps[VLUMP_LIGHTING_LDR].filelen)) l = l2; if (version == 18) @@ -5405,21 +5593,21 @@ static qboolean CModHL2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *lumps, return true; } #ifdef HAVE_CLIENT -static void CModHL2_LoadLighting (model_t *mod, qbyte *mod_base, lump_t *oldl, lump_t *newl) +static void CModHL2_LoadLighting (model_t *mod, qbyte *mod_base, lump_t *ldr, lump_t *hdr) { - if (newl->filelen) - { //this data is screwy. it LOOKS like e8bgr8, but we still get weird results. - mod->lightmaps.fmt = LM_E8BGR8; - mod->lightdatasize = newl->filelen; - mod->lightdata = ZG_Malloc(&mod->memgroup, mod->lightdatasize); - memcpy(mod->lightdata, (void *)(mod_base + newl->fileofs), mod->lightdatasize); - } - else if (oldl->filelen) + if (hdr->filelen && !(hl2_favour_ldr.ival && ldr->filelen)) { mod->lightmaps.fmt = LM_E8BGR8; - mod->lightdatasize = oldl->filelen; + mod->lightdatasize = hdr->filelen; mod->lightdata = ZG_Malloc(&mod->memgroup, mod->lightdatasize); - memcpy(mod->lightdata, (void *)(mod_base + oldl->fileofs), mod->lightdatasize); + memcpy(mod->lightdata, (void *)(mod_base + hdr->fileofs), mod->lightdatasize); + } + else if (ldr->filelen) + { + mod->lightmaps.fmt = LM_E8BGR8; + mod->lightdatasize = ldr->filelen; + mod->lightdata = ZG_Malloc(&mod->memgroup, mod->lightdatasize); + memcpy(mod->lightdata, (void *)(mod_base + ldr->fileofs), mod->lightdatasize); } } #endif @@ -5658,7 +5846,7 @@ static qboolean CModHL2_LoadStaticProps(model_t *mod, qbyte *offset, size_t size } } //Hack: lighting is wrong. - ent->light_known = 1; + ent->light_type = ELT_UNKNOWN; VectorSet(ent->light_dir, 0, 0.707, 0.707); VectorSet(ent->light_avg, 0.75, 0.75, 0.75); VectorSet(ent->light_range, 0.5, 0.5, 0.5); @@ -5761,7 +5949,7 @@ static qboolean VBSP_LoadModel(model_t *mod, qbyte *mod_base, size_t filelen, ch noerrors = noerrors && Mod_LoadSurfedges (mod, mod_base, &header.lumps[VLUMP_SURFEDGES]); #ifdef HAVE_CLIENT if (noerrors && haverenderer) - CModHL2_LoadLighting (mod, mod_base, &header.lumps[VLUMP_LIGHTING], &header.lumps[VLUMP_LIGHTING_HDR]); + CModHL2_LoadLighting (mod, mod_base, &header.lumps[VLUMP_LIGHTING_LDR], &header.lumps[VLUMP_LIGHTING_HDR]); #endif noerrors = noerrors && CModHL2_LoadSurfaces (mod, mod_base, &header.lumps[VLUMP_TEXINFO]); noerrors = noerrors && CModQ2_LoadPlanes (mod, mod_base, &header.lumps[VLUMP_PLANES]); @@ -5780,6 +5968,11 @@ static qboolean VBSP_LoadModel(model_t *mod, qbyte *mod_base, size_t filelen, ch noerrors = noerrors && CModQ2_LoadSubmodels (mod, mod_base, &header.lumps[VLUMP_MODELS]); noerrors = noerrors && CModQ2_LoadAreas (mod, mod_base, &header.lumps[VLUMP_AREAS]); noerrors = noerrors && CModHL2_LoadAreaPortals (mod, mod_base, &header.lumps[VLUMP_AREAPORTALS], &header.lumps[VLUMP_AREAPORTALVERTS]); +#ifdef HAVE_CLIENT + if (noerrors && haverenderer) + CModHL2_LoadLeafLight (mod, mod_base, &header.lumps[VLUMP_LEAFLIGHTI_HDR], &header.lumps[VLUMP_LEAFLIGHTI_LDR], + &header.lumps[VLUMP_LEAFLIGHTV_HDR], &header.lumps[VLUMP_LEAFLIGHTV_LDR], header.version); +#endif noerrors = noerrors && CModHL2_LoadGameLump (mod, mod_base, &header.lumps[VLUMP_GAMELUMP]); if (!noerrors) @@ -5790,7 +5983,7 @@ static qboolean VBSP_LoadModel(model_t *mod, qbyte *mod_base, size_t filelen, ch mod->funcs.FindTouchedLeafs = Q23BSP_FindTouchedLeafs; #endif #ifdef HAVE_CLIENT - mod->funcs.LightPointValues = GLQ2BSP_LightPointValues; + mod->funcs.LightPointValues = HL2BSP_LightPointValues; mod->funcs.StainNode = GLR_Q2BSP_StainNode; mod->funcs.MarkLights = Q2BSP_MarkLights; #endif @@ -8728,6 +8921,7 @@ void CM_Init(void) //register cvars. #ifdef HL2BSPS Cvar_Register(&hl2_displacement_scale, MAPOPTIONS); + Cvar_Register(&hl2_favour_ldr, MAPOPTIONS); #endif CM_InitBoxHull (); diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index bd2401a9..28c448e0 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -1350,7 +1350,7 @@ static void R_DrawShadowVolume(mesh_t *mesh) #endif //true if no shading is to be used. -qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel) +void R_CalcModelLighting(entity_t *e, model_t *clmodel) { vec3_t lightdir; int i; @@ -1358,16 +1358,16 @@ qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel) float add, m; vec3_t shadelight, ambientlight; - if (e->light_known) - return e->light_known-1; + if (e->light_type != ELT_UNKNOWN) //don't bother recalculating if its already been calced. + return; e->light_dir[0] = 0; e->light_dir[1] = 1; e->light_dir[2] = 0; if ((clmodel->engineflags & MDLF_FLAME) || r_fullbright.ival) { e->light_avg[0] = e->light_avg[1] = e->light_avg[2] = 1; e->light_range[0] = e->light_range[1] = e->light_range[2] = 0; - e->light_known = 2; - return e->light_known-1; + e->light_type = ELT_FLAT; + return; } if ( #ifdef HEXEN2 @@ -1377,22 +1377,22 @@ qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel) { e->light_avg[0] = e->light_avg[1] = e->light_avg[2] = 1; e->light_range[0] = e->light_range[1] = e->light_range[2] = 0; - e->light_known = 2; - return e->light_known-1; + e->light_type = ELT_FLAT; + return; } if (r_fb_models.ival == 1 && ruleset_allow_fbmodels.ival && (clmodel->engineflags & MDLF_EZQUAKEFBCHEAT) && cls.protocol == CP_QUAKEWORLD && cl.deathmatch) { e->light_avg[0] = e->light_avg[1] = e->light_avg[2] = 1; e->light_range[0] = e->light_range[1] = e->light_range[2] = 0; - e->light_known = 2; - return e->light_known-1; + e->light_type = ELT_FLAT; + return; } if (!(r_refdef.flags & RDF_NOWORLDMODEL)) { if (e->flags & RF_WEAPONMODEL) { - cl.worldmodel->funcs.LightPointValues(cl.worldmodel, r_refdef.vieworg, shadelight, ambientlight, lightdir); + e->light_type = cl.worldmodel->funcs.LightPointValues(cl.worldmodel, r_refdef.vieworg, shadelight, ambientlight, lightdir, e->light_cube); for (i = 0; i < 3; i++) { /*viewmodels may not be pure black*/ if (ambientlight[i] < 24) @@ -1407,9 +1407,9 @@ qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel) VectorAdd(e->origin, center, center); #else VectorCopy(e->origin, center); - center[2] += 24; +// center[2] += 24; #endif - cl.worldmodel->funcs.LightPointValues(cl.worldmodel, center, shadelight, ambientlight, lightdir); + e->light_type = cl.worldmodel->funcs.LightPointValues(cl.worldmodel, center, shadelight, ambientlight, lightdir, e->light_cube); } } else @@ -1579,8 +1579,8 @@ qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel) VectorClear(e->light_range); VectorScale(shadelight, fb, e->light_avg); - e->light_known = 2; - return e->light_known-1; + e->light_type = ELT_FLAT; + return; } else { @@ -1658,9 +1658,6 @@ qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel) VectorMA(ambientlight, 0.5, shadelight, e->light_avg); VectorSubtract(shadelight, ambientlight, e->light_range); } - - e->light_known = 1; - return e->light_known-1; } void R_GAlias_DrawBatch(batch_t *batch) @@ -2871,7 +2868,7 @@ void BE_GenModelBatches(batch_t **batches, const dlight_t *dl, unsigned int bemo VectorSet(r_worldentity.light_avg, 1.0, 1.0, 1.0); VectorSet(r_worldentity.light_range, 0.5, 0.5, 0.5); VectorSet(r_worldentity.light_dir, 0.0, 0.196, 0.98); - r_worldentity.light_known = 1; + r_worldentity.light_type = ELT_LAMBERT; R_GAlias_GenerateBatches(&r_worldentity, batches); } diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index d799ab79..72ee31c9 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -3412,7 +3412,7 @@ static void BE_Program_Set_Attributes(const program_t *prog, struct programpermu for (i = perm->numparms; i > 0; i--, p++) { ph = p->handle; - switch(p->type) + safeswitch(p->type) { /* case SP_UBO_ENTITYINFO: @@ -3666,23 +3666,23 @@ static void BE_Program_Set_Attributes(const program_t *prog, struct programpermu break; case SP_E_GLOWMOD: - qglUniform3fvARB(ph, 1, (GLfloat*)shaderstate.curentity->glowmod); + qglUniform3fvARB(ph, 1, (const GLfloat*)shaderstate.curentity->glowmod); break; case SP_E_ORIGIN: - qglUniform3fvARB(ph, 1, (GLfloat*)shaderstate.curentity->origin); + qglUniform3fvARB(ph, 1, (const GLfloat*)shaderstate.curentity->origin); break; case SP_E_COLOURS: - qglUniform4fvARB(ph, 1, (GLfloat*)shaderstate.curentity->shaderRGBAf); + qglUniform4fvARB(ph, 1, (const GLfloat*)shaderstate.curentity->shaderRGBAf); break; case SP_S_COLOUR: if (shaderstate.colourarraytype) qglUniform4fARB(ph, 1, 1, 1, 1); //invalid use else - qglUniform4fvARB(ph, 1, (GLfloat*)shaderstate.pendingcolourflat); + qglUniform4fvARB(ph, 1, (const GLfloat*)shaderstate.pendingcolourflat); break; case SP_E_COLOURSIDENT: if (shaderstate.flags & BEF_FORCECOLOURMOD) - qglUniform4fvARB(ph, 1, (GLfloat*)shaderstate.curentity->shaderRGBAf); + qglUniform4fvARB(ph, 1, (const GLfloat*)shaderstate.curentity->shaderRGBAf); else qglUniform4fARB(ph, 1, 1, 1, shaderstate.curentity->shaderRGBAf[3]); break; @@ -3814,19 +3814,28 @@ static void BE_Program_Set_Attributes(const program_t *prog, struct programpermu /*static lighting info*/ case SP_E_L_DIR: - qglUniform3fvARB(ph, 1, (float*)shaderstate.curentity->light_dir); + qglUniform3fvARB(ph, 1, (const float*)shaderstate.curentity->light_dir); break; case SP_E_L_MUL: if (shaderstate.mode == BEM_DEPTHDARK) qglUniform3fvARB(ph, 1, vec3_origin); else - qglUniform3fvARB(ph, 1, (float*)shaderstate.curentity->light_range); + qglUniform3fvARB(ph, 1, (const float*)shaderstate.curentity->light_range); break; case SP_E_L_AMBIENT: if (shaderstate.mode == BEM_DEPTHDARK) qglUniform3fvARB(ph, 1, vec3_origin); else - qglUniform3fvARB(ph, 1, (float*)shaderstate.curentity->light_avg); + qglUniform3fvARB(ph, 1, (const float*)shaderstate.curentity->light_avg); + break; + case SP_E_L_AMBIENTCUBE: + if (shaderstate.mode == BEM_DEPTHDARK) + { + static vec3_t nulllightcube[6]; + qglUniform3fvARB(ph, 6, (const float*)nulllightcube); + } + else + qglUniform3fvARB(ph, 6, (const float*)shaderstate.curentity->light_cube); break; case SP_E_TIME: @@ -3861,7 +3870,19 @@ static void BE_Program_Set_Attributes(const program_t *prog, struct programpermu qglUniform3fvARB(ph, 1, ((cvar_t*)p->pval)->vec4); break; - default: + case SP_CONST2I: + //qglUniform2iARB(ph, p->ival[0], p->ival[1], 0); + //break; + case SP_CONST3I: + //qglUniform3iARB(ph, p->ival[0], p->ival[1], p->ival[2]); + //break; + case SP_CONST4I: + //qglUniform4iARB(ph, p->ival[0], p->ival[1], p->ival[2], p->ival[3]); + //break; + case SP_BAD: + case SP_FIRSTIMMEDIATE: + case SP_M_ENTBONES_MAT4: + safedefault: Host_EndGame("Bad shader program parameter type (%i)", p->type); break; } @@ -3891,6 +3912,8 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas perm |= PERMUTATION_UPPERLOWER; if (r_refdef.globalfog.density) perm |= PERMUTATION_FOG; + if (shaderstate.curentity->light_type==ELT_CUBE) + perm |= PERMUTATION_AMBIENTCUBE; // if (TEXLOADED(shaderstate.curtexnums->bump) && shaderstate.curbatch->lightmap[0] >= 0 && lightmap[shaderstate.curbatch->lightmap[0]]->hasdeluxe) // perm |= PERMUTATION_DELUXE; if ((TEXLOADED(shaderstate.curtexnums->reflectcube) || TEXLOADED(shaderstate.curtexnums->reflectmask))) @@ -3904,6 +3927,7 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas permu = p->permu[perm]; if (!permu) { + Con_DLPrintf(2, "%s: Lazy permutation load - %x\n", p->name, perm); p->permu[perm] = permu = Shader_LoadPermutation(p, perm); if (!permu) { //failed? copy from 0 so we don't keep re-failing diff --git a/engine/gl/gl_heightmap.c b/engine/gl/gl_heightmap.c index 049d8e97..ab802669 100644 --- a/engine/gl/gl_heightmap.c +++ b/engine/gl/gl_heightmap.c @@ -4444,7 +4444,7 @@ void Heightmap_FindTouchedLeafs (model_t *mod, pvscache_t *ent, const float *min } #endif -void Heightmap_LightPointValues (model_t *mod, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir) +enum entlighttype_e Heightmap_LightPointValues (model_t *mod, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir, vec3_t res_cube[6]) { res_diffuse[0] = 128; res_diffuse[1] = 128; @@ -4456,6 +4456,7 @@ void Heightmap_LightPointValues (model_t *mod, const vec3_t point, vec3_t res_di res_dir[1] = 0;//cos(time); res_dir[2] = 0;//sin(time); VectorNormalize(res_dir); + return ELT_LAMBERT; } void Heightmap_StainNode (mnode_t *node, float *parms) { diff --git a/engine/gl/gl_model.h b/engine/gl/gl_model.h index d497f19f..e934b895 100644 --- a/engine/gl/gl_model.h +++ b/engine/gl/gl_model.h @@ -283,7 +283,7 @@ typedef struct { qboolean (*EdictInFatPVS) (struct model_s *model, const struct pvscache_s *edict, const qbyte *pvs, const int *areas); //areas[0] is the count of accepted areas, if valid. void (*FindTouchedLeafs) (struct model_s *model, struct pvscache_s *ent, const vec3_t cullmins, const vec3_t cullmaxs); //edict system as opposed to q2 game dll system. - void (*LightPointValues) (struct model_s *model, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir); + enum entlighttype_e (*LightPointValues) (struct model_s *model, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir, vec3_t res_cube[6]); void (*StainNode) (struct mnode_s *node, float *parms); void (*MarkLights) (struct dlight_s *light, dlightbitmask_t bit, struct mnode_s *node); @@ -636,7 +636,7 @@ size_t Fragment_ClipPlaneToBrush(vecV_t *points, size_t maxpoints, void *planes, void Mod_ClipDecal(struct model_s *mod, vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangent2, float size, unsigned int surfflagmask, unsigned int surflagmatch, void (*callback)(void *ctx, vec3_t *fte_restrict points, size_t numpoints, shader_t *shader), void *ctx); void Q1BSP_MarkLights (dlight_t *light, dlightbitmask_t bit, mnode_t *node); -void GLQ1BSP_LightPointValues(struct model_s *model, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir); +enum entlighttype_e GLQ1BSP_LightPointValues(struct model_s *model, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir, vec3_t res_cube[6]); qboolean Q1BSP_RecursiveHullCheck (hull_t *hull, int num, const vec3_t p1, const vec3_t p2, unsigned int hitcontents, struct trace_s *trace); /* diff --git a/engine/gl/gl_rlight.c b/engine/gl/gl_rlight.c index 14b2a5cf..595951a9 100644 --- a/engine/gl/gl_rlight.c +++ b/engine/gl/gl_rlight.c @@ -68,7 +68,7 @@ void R_UpdateHDR(vec3_t org) if (r_hdr_irisadaptation.ival && cl.worldmodel && !(r_refdef.flags & RDF_NOWORLDMODEL)) { //fake and lame, but whatever. - vec3_t ambient, diffuse, dir; + vec3_t ambient, diffuse, dir, cube[6]; float lev = 0; #ifdef RTLIGHTS @@ -79,7 +79,7 @@ void R_UpdateHDR(vec3_t org) if (!r_shadow_realtime_world.ival || r_shadow_realtime_world_lightmaps.value) #endif { - cl.worldmodel->funcs.LightPointValues(cl.worldmodel, org, ambient, diffuse, dir); + cl.worldmodel->funcs.LightPointValues(cl.worldmodel, org, ambient, diffuse, dir, cube); lev += (VectorLength(ambient) + VectorLength(diffuse))/256; } @@ -2346,7 +2346,7 @@ static void GLQ3_AddLatLong(const qbyte latlong[2], vec3_t dir, float mag) dir[2] += mag * cos ( lat ); } -void GLQ3_LightGrid(model_t *mod, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir) +enum entlighttype_e GLQ3_LightGrid(model_t *mod, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir, vec3_t res_cube[6]) { q3lightgridinfo_t *lg = (q3lightgridinfo_t *)mod->lightgrid; int index[8]; @@ -2378,7 +2378,7 @@ void GLQ3_LightGrid(model_t *mod, const vec3_t point, vec3_t res_diffuse, vec3_t res_dir[1] = 1; res_dir[2] = 0.1; } - return; + return ELT_LAMBERT; } //If in doubt, steal someone else's code... @@ -2458,6 +2458,8 @@ void GLQ3_LightGrid(model_t *mod, const vec3_t point, vec3_t res_diffuse, vec3_t VectorAdd(diffuse, ambient, res_diffuse); if (res_dir) VectorCopy(direction, res_dir); + + return ELT_LAMBERT; } static int GLRecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) @@ -2616,7 +2618,7 @@ int R_LightPoint (vec3_t p) if (cl.worldmodel->fromgame == fg_quake3) { - GLQ3_LightGrid(cl.worldmodel, p, NULL, end, NULL); + GLQ3_LightGrid(cl.worldmodel, p, NULL, end, NULL, NULL); return (end[0] + end[1] + end[2])/3; } @@ -2925,7 +2927,7 @@ static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, const vec3_t #endif -void GLQ1BSP_LightPointValues(model_t *model, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir) +enum entlighttype_e GLQ1BSP_LightPointValues(model_t *model, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir, vec3_t res_cube[6]) { vec3_t end; float *r; @@ -2949,7 +2951,7 @@ void GLQ1BSP_LightPointValues(model_t *model, const vec3_t point, vec3_t res_dif res_dir[1] = 1; res_dir[2] = 0.1; VectorNormalize(res_dir); - return; + return ELT_LAMBERT; } end[0] = point[0]; @@ -3000,6 +3002,7 @@ void GLQ1BSP_LightPointValues(model_t *model, const vec3_t point, vec3_t res_dif VectorScale(res_ambient, lm, res_ambient); } #endif + return ELT_LAMBERT; } #endif diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index f265477f..be37aa51 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -1361,7 +1361,8 @@ static struct {"SKELETAL", PERMUTATION_SKELETAL}, {"FOG", PERMUTATION_FOG}, {"FRAMEBLEND", PERMUTATION_FRAMEBLEND}, - {"LIGHTSTYLED", PERMUTATION_LIGHTSTYLES} + {"LIGHTSTYLED", PERMUTATION_LIGHTSTYLES}, + {"AMBIENTCUBE", PERMUTATION_AMBIENTCUBE}, }; #define MAXMODIFIERS 64 @@ -2340,6 +2341,7 @@ struct shader_field_names_s shader_unif_names[] = /**/{"e_light_dir", SP_E_L_DIR}, //lightgrid light dir. dotproducts should be clamped to 0-1. /**/{"e_light_mul", SP_E_L_MUL}, //lightgrid light scaler. /**/{"e_light_ambient", SP_E_L_AMBIENT}, //lightgrid light value for the unlit side. +/**/{"e_light_ambientcube", SP_E_L_AMBIENTCUBE},//6 lightgrid light values. {"s_colour", SP_S_COLOUR}, //the rgbgen/alphagen stuff. obviously doesn't work with per-vertex ones. diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index 56c69b87..1b7682e4 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -1547,10 +1547,14 @@ static const char *glsl_hdrs[] = "uniform vec4 e_colourident;" "uniform vec3 e_glowmod;" "uniform vec3 e_uppercolour;" - "uniform vec3 e_lowercolour;" + "uniform vec3 e_lowercolour;\n" + "#ifdef AMBIENTCUBE\n" + "uniform vec3 e_light_ambientcube[6];\n" + "#else\n" "uniform vec3 e_light_dir;" "uniform vec3 e_light_mul;" - "uniform vec3 e_light_ambient;" + "uniform vec3 e_light_ambient;\n" + "#endif\n" /*rtlight properties, use with caution*/ "uniform vec2 l_lightscreen;" diff --git a/engine/gl/glquake.h b/engine/gl/glquake.h index 2c04f59c..febb7c71 100644 --- a/engine/gl/glquake.h +++ b/engine/gl/glquake.h @@ -390,7 +390,7 @@ void R_InitFlashblends(void); #ifdef GLQUAKE void GLR_MarkQ2Lights (dlight_t *light, int bit, mnode_t *node); #endif -void GLQ3_LightGrid(model_t *mod, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir); +enum entlighttype_e GLQ3_LightGrid(model_t *mod, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir, vec3_t res_cube[6]); qboolean R_LoadRTLights(void); qboolean R_ImportRTLights(const char *entlump); diff --git a/engine/gl/shader.h b/engine/gl/shader.h index 8756864c..418554cf 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -373,6 +373,9 @@ enum{ #define PERMUTATION_LIGHTSTYLES 0u #endif + #define PERMUTATION_AMBIENTCUBE (1u<loadstate == MLS_LOADED && wm->funcs.LightPointValues && wm->lightmaps.maxstylefuncs.LightPointValues(wm, point, diffuse, ambient, dir); + wm->funcs.LightPointValues(wm, point, diffuse, ambient, dir, cube); VectorMA(ambient, 0.5, diffuse, G_VECTOR(OFS_RETURN)); return; } diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index 43a81cb1..981dfa51 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -7283,7 +7283,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse) //fixme: should probably support rtlights, but this is a server, so urgh. if (sv.world.worldmodel && sv.world.worldmodel->funcs.LightPointValues) { - vec3_t diffuse, ambient, dir; + vec3_t diffuse, ambient, dir, cube[6]; float lev = 0; #if defined(RTLIGHTS) && !defined(SERVERONLY) Sh_CalcPointLight(sv_player->v->origin, ambient); @@ -7292,7 +7292,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse) if (!r_shadow_realtime_world.ival || r_shadow_realtime_world_lightmaps.value) #endif { - sv.world.worldmodel->funcs.LightPointValues(sv.world.worldmodel, sv_player->v->origin, ambient, diffuse, dir); + sv.world.worldmodel->funcs.LightPointValues(sv.world.worldmodel, sv_player->v->origin, ambient, diffuse, dir, cube); lev += (VectorLength(ambient) + VectorLength(diffuse)/2.0)/256; } sv_player->xv->light_level = lev * 255; diff --git a/engine/shaders/glsl/vmt_refract.glsl b/engine/shaders/glsl/vmt_refract.glsl index ab44aed2..fa561496 100644 --- a/engine/shaders/glsl/vmt_refract.glsl +++ b/engine/shaders/glsl/vmt_refract.glsl @@ -33,7 +33,7 @@ varying vec3 eyeminusvertex; vec4 out_f = vec4( 1.0, 1.0, 1.0, 1.0 ); norm_f = ( texture2D( s_normalmap, tex_c).xyz); - norm_f.g *= -1.0f; + norm_f.g *= -1.0; norm_f = normalize( norm_f ); // Reflection/View coordinates diff --git a/engine/shaders/glsl/vmt_vertexlit.glsl b/engine/shaders/glsl/vmt_vertexlit.glsl index 73c4844b..8b53ccd1 100644 --- a/engine/shaders/glsl/vmt_vertexlit.glsl +++ b/engine/shaders/glsl/vmt_vertexlit.glsl @@ -3,8 +3,8 @@ !!permu BUMP !!permu FOG !!permu SKELETAL +!!permu AMBIENTCUBE !!samps diffuse fullbright normalmap - !!permu FAKESHADOWS !!cvardf r_glsl_pcf !!samps =FAKESHADOWS shadowmap @@ -104,11 +104,18 @@ varying vec3 norm; diffuse_f.rgb += (textureCube(s_reflectcube, cube_c).rgb * vec3(refl,refl,refl)); #endif -#ifdef HALFLAMBERT - light = e_light_ambient + (e_light_mul * halflambert(norm, e_light_dir)); +#ifdef AMBIENTCUBE + //no specular effect here. use rtlights for that. + vec3 nn = norm*norm; //FIXME: should be worldspace normal. + light = nn.x * e_light_ambientcube[(norm.x<0.0)?1:0] + + nn.y * e_light_ambientcube[(norm.y<0.0)?3:2] + + nn.z * e_light_ambientcube[(norm.z<0.0)?5:4]; #else + #ifdef HALFLAMBERT + light = e_light_ambient + (e_light_mul * halflambert(norm, e_light_dir)); + #else light = e_light_ambient + (e_light_mul * lambert(norm, e_light_dir)); -#endif + #endif /* the light we're getting is always too bright */ light *= 0.75; @@ -120,6 +127,7 @@ varying vec3 norm; light.g = 1.5; if (light.b > 1.5) light.b = 1.5; +#endif diffuse_f.rgb *= light;