fix wireframe.

increase xz memory limit
fix fseek/fsize to match definitions.
r_deluxemapping is more aggressive with regards to generating lux files on demand (but won't generate lit data at the same time).
fix webgl shader issues.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5071 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2017-03-06 14:06:12 +00:00
parent c385cb71b4
commit dadec86338
14 changed files with 449 additions and 403 deletions

View File

@ -1335,7 +1335,7 @@ static void PM_ListDownloaded(struct dl_download *dl)
if (!downloadablelist[i].received)
break;
}
if (domanifestinstall == MANIFEST_SECURITY_INSTALLER)
if (domanifestinstall == MANIFEST_SECURITY_INSTALLER && manifestpackage)
{
package_t *meta;
meta = PM_MarkedPackage(manifestpackage);

View File

@ -510,7 +510,7 @@ struct relight_ctx_s;
struct llightinfo_s;
void LightFace (struct relight_ctx_s *ctx, struct llightinfo_s *threadctx, int surfnum); //version that is aware of bsp trees
void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *threadctx, qbyte surf_styles[4], qbyte *surf_rgbsamples, qbyte *surf_deluxesamples, vec4_t surf_plane, vec4_t surf_texplanes[2], vec2_t exactmins, vec2_t exactmaxs, int texmins[2], int texsize[2], float lmscale); //special version that doesn't know what a face is or anything.
struct relight_ctx_s *LightStartup(struct relight_ctx_s *ctx, struct model_s *model, qboolean shadows);
struct relight_ctx_s *LightStartup(struct relight_ctx_s *ctx, struct model_s *model, qboolean shadows, qboolean skiplit);
void LightReloadEntities(struct relight_ctx_s *ctx, const char *entstring, qboolean ignorestyles);
void LightShutdown(struct relight_ctx_s *ctx, struct model_s *mod);
extern const size_t lightthreadctxsize;

View File

@ -115,7 +115,7 @@ cvar_t com_highlightcolor = CVARD("com_highlightcolor", STRINGIFY(COLOR_RED), "A
cvar_t com_nogamedirnativecode = CVARFD("com_nogamedirnativecode", "1", CVAR_NOTFROMSERVER, FULLENGINENAME" blocks all downloads of files with a .dll or .so extension, however other engines (eg: ezquake and fodquake) do not - this omission can be used to trigger delayed eremote exploits in any engine (including "DISTRIBUTION") which is later run from the same gamedir.\nQuake2, Quake3(when debugging), and KTX typically run native gamecode from within gamedirs, so if you wish to run any of these games you will need to ensure this cvar is changed to 0, as well as ensure that you don't run unsafe clients.\n");
cvar_t sys_platform = CVAR("sys_platform", PLATFORM);
cvar_t pm_downloads_url = CVARFD("pm_downloads_url", NULL, CVAR_NOTFROMSERVER|CVAR_NOSAVE|CVAR_NOSET, "The URL of a package updates list."); //read from the default.fmf
cvar_t pm_autoupdate = CVARFD("pm_autoupdate", "1", CVAR_NOTFROMSERVER|CVAR_NOSAVE|CVAR_NOSET, "0: off.\n1: enabled (stable only).\n2: enabled (unstable).\nNote that autoupdate will still prompt the user to actually apply the changes."); //read from the package list only.
cvar_t pm_autoupdate = CVARFD("pm_autoupdate", "1", CVAR_NOTFROMSERVER|CVAR_ARCHIVE, "0: off.\n1: enabled (stable only).\n2: enabled (unstable).\nNote that autoupdate will still prompt the user to actually apply the changes."); //read from the package list only.
qboolean com_modified; // set true if using non-id files

View File

@ -3092,7 +3092,7 @@ vfsfile_t *FS_XZ_DecompressWriteFilter(vfsfile_t *outfile)
n->outfile = outfile;
n->s = xz_dec_init(XZ_DYNALLOC, 1 << 26);
n->s = xz_dec_init(XZ_DYNALLOC, 1 << 27);
if (!n->s)
{
Z_Free(n);

View File

@ -2266,7 +2266,7 @@ void QCBUILTIN PF_fread (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals
void QCBUILTIN PF_fseek (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int fnum = G_FLOAT(OFS_PARM0) - FIRST_QC_FILE_INDEX;
G_INT(OFS_PARM1) = 0;
G_INT(OFS_RETURN) = -1;
if (fnum < 0 || fnum >= MAX_QC_FILES)
{
PF_Warningf(prinst, "PF_fread: File out of range\n");
@ -2283,16 +2283,16 @@ void QCBUILTIN PF_fseek (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals
return; //this just isn't ours.
}
G_INT(OFS_PARM1) = pf_fopen_files[fnum].ofs;
if (prinst->callargc>1 && G_INT(OFS_PARM0) >= 0)
G_INT(OFS_RETURN) = pf_fopen_files[fnum].ofs;
if (prinst->callargc>1 && G_INT(OFS_PARM1) >= 0)
{
pf_fopen_files[fnum].ofs = G_INT(OFS_PARM0);
pf_fopen_files[fnum].ofs = G_INT(OFS_PARM1);
}
}
void QCBUILTIN PF_fsize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int fnum = G_FLOAT(OFS_PARM0) - FIRST_QC_FILE_INDEX;
G_INT(OFS_PARM1) = 0;
G_INT(OFS_RETURN) = -1;
if (fnum < 0 || fnum >= MAX_QC_FILES)
{
PF_Warningf(prinst, "PF_fsize: File out of range\n");
@ -2309,10 +2309,10 @@ void QCBUILTIN PF_fsize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals
return; //this just isn't ours.
}
G_INT(OFS_PARM1) = pf_fopen_files[fnum].len;
if (prinst->callargc>1 && G_INT(OFS_PARM0) >= 0)
G_INT(OFS_RETURN) = pf_fopen_files[fnum].len;
if (prinst->callargc>1 && G_INT(OFS_PARM1) >= 0)
{
size_t newlen = G_INT(OFS_PARM0);
size_t newlen = G_INT(OFS_PARM1);
PF_fresizebuffer_internal(&pf_fopen_files[fnum], newlen);
pf_fopen_files[fnum].len = min(pf_fopen_files[fnum].bufferlen, newlen);
}

View File

@ -91,6 +91,7 @@ struct {
const shader_t *crepskyshader;
const shader_t *crepopaqueshader;
const shader_t *depthonlyshader;
const shader_t *wireframeshader;
union programhandle_u allblackshader;
int allblack_mvp;
@ -3573,6 +3574,15 @@ void GLBE_SelectMode(backendmode_t mode)
default:
break;
case BEM_WIREFRAME:
if (!shaderstate.wireframeshader && gl_config.arb_shader_objects)
shaderstate.wireframeshader = R_RegisterShader("wireframe", SUF_NONE,
"{\n"
"program wireframe\n"
"{\n"
"nodepthtest\n"
"}\n"
"}\n"
);
break;
case BEM_DEPTHONLY:
#ifndef GLSLONLY
@ -4128,31 +4138,35 @@ static void DrawMeshes(void)
break;
case BEM_WIREFRAME:
//FIXME: do this with a shader instead? its not urgent as we can draw the shader normally anyway, just faster.
//FIXME: we need to use a shader for vertex blending. not really an issue with mdl, but more significant with iqms (base pose!).
if (shaderstate.wireframeshader && shaderstate.wireframeshader->prog)
{
shaderstate.pendingcolourvbo = shaderstate.sourcevbo->colours[0].gl.vbo;
shaderstate.pendingcolourpointer = shaderstate.sourcevbo->colours[0].gl.addr;
shaderstate.colourarraytype = shaderstate.sourcevbo->colours_bytes?GL_UNSIGNED_BYTE:GL_FLOAT;
shaderstate.pendingtexcoordparts[0] = 2;
shaderstate.pendingtexcoordvbo[0] = shaderstate.sourcevbo->texcoord.gl.vbo;
shaderstate.pendingtexcoordpointer[0] = shaderstate.sourcevbo->texcoord.gl.addr;
BE_RenderMeshProgram(shaderstate.wireframeshader, shaderstate.wireframeshader->passes, shaderstate.wireframeshader->prog);
}
#ifndef GLSLONLY
if (!gl_config_nofixedfunc)
else if (gl_config_nofixedfunc)
{
BE_SetPassBlendMode(0, PBM_REPLACE);
GL_DeSelectProgram();
shaderstate.pendingcolourvbo = 0;
shaderstate.pendingcolourpointer = NULL;
Vector4Set(shaderstate.pendingcolourflat, 1, 1, 1, 1);
while(shaderstate.lastpasstmus>0)
{
GL_LazyBind(--shaderstate.lastpasstmus, 0, r_nulltex);
}
BE_SendPassBlendDepthMask((shaderstate.curshader->passes[0].shaderbits & ~SBITS_BLEND_BITS) | SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA | ((r_wireframe.ival == 1)?SBITS_MISC_NODEPTHTEST:0));
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX) | (1u<<VATTR_LEG_COLOUR), 0);
BE_SubmitMeshChain(false);
}
else
#endif
{
break;
}
shaderstate.pendingcolourvbo = 0;
shaderstate.pendingcolourpointer = NULL;
Vector4Set(shaderstate.pendingcolourflat, 1, 1, 1, 1);
while(shaderstate.lastpasstmus>0)
{
GL_LazyBind(--shaderstate.lastpasstmus, 0, r_nulltex);
}
BE_SendPassBlendDepthMask((shaderstate.curshader->passes[0].shaderbits & ~SBITS_BLEND_BITS) | SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA | ((r_wireframe.ival == 1)?SBITS_MISC_NODEPTHTEST:0));
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX) | (1u<<VATTR_LEG_COLOUR), 0);
BE_SubmitMeshChain(false);
break;
case BEM_DEPTHDARK:
if ((shaderstate.curshader->flags & SHADER_HASLIGHTMAP) && !TEXVALID(shaderstate.curtexnums->fullbright))

View File

@ -7002,7 +7002,7 @@ qboolean Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities)
#ifdef RUNTIMELIGHTING
hm->entsdirty = true;
hm->relightcontext = LightStartup(NULL, mod, false);
hm->relightcontext = LightStartup(NULL, mod, false, false);
hm->lightthreadmem = BZ_Malloc(lightthreadctxsize);
hm->inheritedlightthreadmem = false;
#endif
@ -7098,7 +7098,7 @@ qboolean Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities)
submod->loadstate = MLS_LOADED;
#ifdef RUNTIMELIGHTING
subhm->relightcontext = LightStartup(hm->relightcontext, submod, false);
subhm->relightcontext = LightStartup(hm->relightcontext, submod, false, false);
subhm->lightthreadmem = hm->lightthreadmem;
subhm->inheritedlightthreadmem = true;
#endif

View File

@ -1882,10 +1882,16 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean
#endif
#ifdef RUNTIMELIGHTING
if (r_loadlits.value == 2 && !lightmodel && (!litdata || (!luxdata && r_deluxemapping)))
if (!lightmodel && r_loadlits.value == 2 && (!litdata || (!luxdata && r_deluxemapping)))
{
if (!litdata)
writelitfile = true;
writelitfile = !litdata;
numlightdata = l->filelen;
lightmodel = loadmodel;
relitsurface = 0;
}
else if (!lightmodel && r_loadlits.value && r_deluxemapping && !luxdata && !(r_shadow_realtime_world.ival && r_shadow_realtime_world_lightmaps.value<=0))
{ //if deluxemapping is on, generate missing lux files a little more often, but don't bother if we have rtlights on anyway.
writelitfile = false;
numlightdata = l->filelen;
lightmodel = loadmodel;
relitsurface = 0;
@ -5143,7 +5149,7 @@ TRACE(("LoadBrushModel %i\n", __LINE__));
TRACE(("LoadBrushModel %i\n", __LINE__));
if (lightmodel == mod)
{
lightcontext = LightStartup(NULL, lightmodel, true);
lightcontext = LightStartup(NULL, lightmodel, true, !writelitfile);
LightReloadEntities(lightcontext, Mod_GetEntitiesString(lightmodel), false);
}
#endif

View File

@ -1238,6 +1238,9 @@ static const char *glsl_hdrs[] =
"attribute vec4 v_colour4;"
#endif
"\n#endif\n"
"#ifndef USE_ARB_SHADOW\n" //fall back on regular samplers if we must
"#define sampler2DShadow sampler2D\n"
"#endif\n"
#ifndef NOLEGACY
"uniform sampler2DShadow s_shadowmap;"
"uniform samplerCube s_projectionmap;"
@ -1640,108 +1643,118 @@ static const char *glsl_hdrs[] =
"}\n"
,
"sys/pcf.h",
"#ifndef r_glsl_pcf\n"
"#define r_glsl_pcf 9\n"
"#endif\n"
"#if r_glsl_pcf < 1\n"
"#undef r_glsl_pcf\n"
"#define r_glsl_pcf 9\n"
"#endif\n"
"#ifndef DEFS_DEFINED\n"
"uniform vec4 l_shadowmapproj;\n" //light projection matrix info
"uniform vec2 l_shadowmapscale;\n" //xy are the texture scale, z is 1, w is the scale.
"#endif\n"
"vec3 ShadowmapCoord(void)\n"
"{\n"
"#ifdef SPOT\n"
//bias it. don't bother figuring out which side or anything, its not needed
//l_projmatrix contains the light's projection matrix so no other magic needed
"return ((vtexprojcoord.xyz-vec3(0.0,0.0,0.015))/vtexprojcoord.w + vec3(1.0, 1.0, 1.0)) * vec3(0.5, 0.5, 0.5);\n"
//"#elif defined(CUBESHADOW)\n"
// vec3 shadowcoord = vshadowcoord.xyz / vshadowcoord.w;
// #define dosamp(x,y) shadowCube(s_t4, shadowcoord + vec2(x,y)*texscale.xy).r
//!!cvardf r_glsl_pcf
"#ifndef PCF\n"
"#define ShadowmapFilter(smap) 1.0\n" //s_shadowmap generally. returns a scaler to say how much light should be used for this pixel.
"#else\n"
//figure out which axis to use
//texture is arranged thusly:
//forward left up
//back right down
"vec3 dir = abs(vtexprojcoord.xyz);\n"
//assume z is the major axis (ie: forward from the light)
"vec3 t = vtexprojcoord.xyz;\n"
"float ma = dir.z;\n"
"vec3 axis = vec3(0.5/3.0, 0.5/2.0, 0.5);\n"
"if (dir.x > ma)\n"
"{\n"
"ma = dir.x;\n"
"t = vtexprojcoord.zyx;\n"
"axis.x = 0.5;\n"
"}\n"
"if (dir.y > ma)\n"
"{\n"
"ma = dir.y;\n"
"t = vtexprojcoord.xzy;\n"
"axis.x = 2.5/3.0;\n"
"}\n"
//if the axis is negative, flip it.
"if (t.z > 0.0)\n"
"{\n"
"axis.y = 1.5/2.0;\n"
"t.z = -t.z;\n"
"}\n"
//we also need to pass the result through the light's projection matrix too
//the 'matrix' we need only contains 5 actual values. and one of them is a -1. So we might as well just use a vec4.
//note: the projection matrix also includes scalers to pinch the image inwards to avoid sampling over borders, as well as to cope with non-square source image
//the resulting z is prescaled to result in a value between -0.5 and 0.5.
//also make sure we're in the right quadrant type thing
"return axis + ((l_shadowmapproj.xyz*t.xyz + vec3(0.0, 0.0, l_shadowmapproj.w)) / -t.z);\n"
"#endif\n"
"}\n"
"float ShadowmapFilter(sampler2DShadow smap)\n"
"{\n"
"vec3 shadowcoord = ShadowmapCoord();\n"
"#if 0\n"//def GL_ARB_texture_gather
"vec2 ipart, fpart;\n"
"#define dosamp(x,y) textureGatherOffset(smap, ipart.xy, vec2(x,y)))\n"
"vec4 tl = step(shadowcoord.z, dosamp(-1.0, -1.0));\n"
"vec4 bl = step(shadowcoord.z, dosamp(-1.0, 1.0));\n"
"vec4 tr = step(shadowcoord.z, dosamp(1.0, -1.0));\n"
"vec4 br = step(shadowcoord.z, dosamp(1.0, 1.0));\n"
//we now have 4*4 results, woo
//we can just average them for 1/16th precision, but that's still limited graduations
//the middle four pixels are 'full strength', but we interpolate the sides to effectively give 3*3
"vec4 col = vec4(tl.ba, tr.ba) + vec4(bl.rg, br.rg) + " //middle two rows are full strength
"mix(vec4(tl.rg, tr.rg), vec4(bl.ba, br.ba), fpart.y);\n" //top+bottom rows
"return dot(mix(col.rgb, col.agb, fpart.x), vec3(1.0/9.0));\n" //blend r+a, gb are mixed because its pretty much free and gives a nicer dot instruction instead of lots of adds.
"#else\n"
"#define dosamp(x,y) shadow2D(smap, shadowcoord.xyz + (vec3(x,y,0.0)*l_shadowmapscale.xyx)).r\n"
"float s = 0.0;\n"
"#if r_glsl_pcf >= 1 && r_glsl_pcf < 5\n"
"s += dosamp(0.0, 0.0);\n"
"return s;\n"
"#elif r_glsl_pcf >= 5 && r_glsl_pcf < 9\n"
"s += dosamp(-1.0, 0.0);\n"
"s += dosamp(0.0, -1.0);\n"
"s += dosamp(0.0, 0.0);\n"
"s += dosamp(0.0, 1.0);\n"
"s += dosamp(1.0, 0.0);\n"
"return s/5.0;\n"
"#else\n"
"s += dosamp(-1.0, -1.0);\n"
"s += dosamp(-1.0, 0.0);\n"
"s += dosamp(-1.0, 1.0);\n"
"s += dosamp(0.0, -1.0);\n"
"s += dosamp(0.0, 0.0);\n"
"s += dosamp(0.0, 1.0);\n"
"s += dosamp(1.0, -1.0);\n"
"s += dosamp(1.0, 0.0);\n"
"s += dosamp(1.0, 1.0);\n"
"return s/9.0;\n"
"#endif\n"
"#ifndef r_glsl_pcf\n"
"#define r_glsl_pcf 9\n"
"#endif\n"
"}\n"
"#if r_glsl_pcf < 1\n"
"#undef r_glsl_pcf\n"
"#define r_glsl_pcf 9\n"
"#endif\n"
"#ifndef DEFS_DEFINED\n"
"uniform vec4 l_shadowmapproj;\n" //light projection matrix info
"uniform vec2 l_shadowmapscale;\n" //xy are the texture scale, z is 1, w is the scale.
"#endif\n"
"vec3 ShadowmapCoord(void)\n"
"{\n"
"#ifdef SPOT\n"
//bias it. don't bother figuring out which side or anything, its not needed
//l_projmatrix contains the light's projection matrix so no other magic needed
"return ((vtexprojcoord.xyz-vec3(0.0,0.0,0.015))/vtexprojcoord.w + vec3(1.0, 1.0, 1.0)) * vec3(0.5, 0.5, 0.5);\n"
//"#elif defined(CUBESHADOW)\n"
// vec3 shadowcoord = vshadowcoord.xyz / vshadowcoord.w;
// #define dosamp(x,y) shadowCube(s_t4, shadowcoord + vec2(x,y)*texscale.xy).r
"#else\n"
//figure out which axis to use
//texture is arranged thusly:
//forward left up
//back right down
"vec3 dir = abs(vtexprojcoord.xyz);\n"
//assume z is the major axis (ie: forward from the light)
"vec3 t = vtexprojcoord.xyz;\n"
"float ma = dir.z;\n"
"vec3 axis = vec3(0.5/3.0, 0.5/2.0, 0.5);\n"
"if (dir.x > ma)\n"
"{\n"
"ma = dir.x;\n"
"t = vtexprojcoord.zyx;\n"
"axis.x = 0.5;\n"
"}\n"
"if (dir.y > ma)\n"
"{\n"
"ma = dir.y;\n"
"t = vtexprojcoord.xzy;\n"
"axis.x = 2.5/3.0;\n"
"}\n"
//if the axis is negative, flip it.
"if (t.z > 0.0)\n"
"{\n"
"axis.y = 1.5/2.0;\n"
"t.z = -t.z;\n"
"}\n"
//we also need to pass the result through the light's projection matrix too
//the 'matrix' we need only contains 5 actual values. and one of them is a -1. So we might as well just use a vec4.
//note: the projection matrix also includes scalers to pinch the image inwards to avoid sampling over borders, as well as to cope with non-square source image
//the resulting z is prescaled to result in a value between -0.5 and 0.5.
//also make sure we're in the right quadrant type thing
"return axis + ((l_shadowmapproj.xyz*t.xyz + vec3(0.0, 0.0, l_shadowmapproj.w)) / -t.z);\n"
"#endif\n"
"}\n"
"float ShadowmapFilter(sampler2DShadow smap)\n"
"{\n"
"vec3 shadowcoord = ShadowmapCoord();\n"
"#if 0\n"//def GL_ARB_texture_gather
"vec2 ipart, fpart;\n"
"#define dosamp(x,y) textureGatherOffset(smap, ipart.xy, vec2(x,y)))\n"
"vec4 tl = step(shadowcoord.z, dosamp(-1.0, -1.0));\n"
"vec4 bl = step(shadowcoord.z, dosamp(-1.0, 1.0));\n"
"vec4 tr = step(shadowcoord.z, dosamp(1.0, -1.0));\n"
"vec4 br = step(shadowcoord.z, dosamp(1.0, 1.0));\n"
//we now have 4*4 results, woo
//we can just average them for 1/16th precision, but that's still limited graduations
//the middle four pixels are 'full strength', but we interpolate the sides to effectively give 3*3
"vec4 col = vec4(tl.ba, tr.ba) + vec4(bl.rg, br.rg) + " //middle two rows are full strength
"mix(vec4(tl.rg, tr.rg), vec4(bl.ba, br.ba), fpart.y);\n" //top+bottom rows
"return dot(mix(col.rgb, col.agb, fpart.x), vec3(1.0/9.0));\n" //blend r+a, gb are mixed because its pretty much free and gives a nicer dot instruction instead of lots of adds.
"#else\n"
"#ifdef USE_ARB_SHADOW\n"
//with arb_shadow, we can benefit from hardware acclerated pcf, for smoother shadows
"#define dosamp(x,y) shadow2D(smap, shadowcoord.xyz + (vec3(x,y,0.0)*l_shadowmapscale.xyx))\n"
"#else\n"
"#define dosamp(x,y) float(texture2D(smap, shadowcoord.xy + (vec2(x,y)*l_shadowmapscale.xy)).r >= shadowcoord.z)\n"
"#endif\n"
"float s = 0.0;\n"
"#if r_glsl_pcf >= 1 && r_glsl_pcf < 5\n"
"s += dosamp(0.0, 0.0);\n"
"return s;\n"
"#elif r_glsl_pcf >= 5 && r_glsl_pcf < 9\n"
"s += dosamp(-1.0, 0.0);\n"
"s += dosamp(0.0, -1.0);\n"
"s += dosamp(0.0, 0.0);\n"
"s += dosamp(0.0, 1.0);\n"
"s += dosamp(1.0, 0.0);\n"
"return s/5.0;\n"
"#else\n"
"s += dosamp(-1.0, -1.0);\n"
"s += dosamp(-1.0, 0.0);\n"
"s += dosamp(-1.0, 1.0);\n"
"s += dosamp(0.0, -1.0);\n"
"s += dosamp(0.0, 0.0);\n"
"s += dosamp(0.0, 1.0);\n"
"s += dosamp(1.0, -1.0);\n"
"s += dosamp(1.0, 0.0);\n"
"s += dosamp(1.0, 1.0);\n"
"return s/9.0;\n"
"#endif\n"
"#endif\n"
"}\n"
"#endif\n"
,
NULL
};

View File

@ -21,6 +21,7 @@ struct relight_ctx_s
unsigned int nummodels;
model_t *models[2048];
qboolean skiplit; //lux only
qboolean shadows;
mentity_t *entities;
unsigned int num_entities;
@ -134,12 +135,13 @@ void LightShutdown(struct relight_ctx_s *ctx, model_t *mod)
Z_Free(ctx->entities);
Z_Free(ctx);
}
struct relight_ctx_s *LightStartup(struct relight_ctx_s *ctx, model_t *model, qboolean shadows)
struct relight_ctx_s *LightStartup(struct relight_ctx_s *ctx, model_t *model, qboolean shadows, qboolean skiplit)
{
if (!ctx)
{
ctx = Z_Malloc(sizeof(*ctx));
ctx->shadows = shadows;
ctx->skiplit = skiplit;
}
ctx->models[ctx->nummodels++] = model;
return ctx;
@ -848,7 +850,10 @@ void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *l, qbyte surf_s
dulout = GetNormFileSpace (f->lightofs, lightmapsize);
}
#else
rgbout = surf_rgbsamples;
if (!ctx->skiplit)
rgbout = surf_rgbsamples;
else
rgbout = NULL;
if (l->ctx->models[0]->deluxdata)
{
dulout = surf_deluxesamples;
@ -909,7 +914,8 @@ void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *l, qbyte surf_s
if (total > 0xff)
total = 0xff;
*rgbout++ = total;
if (rgbout)
*rgbout++ = total;
mean += total;
}
#ifdef UTILITY
@ -925,9 +931,9 @@ void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *l, qbyte surf_s
VectorSet(temp, 0, 0, 1);
else
VectorNormalize(temp);
*dulout++ = (temp[0]+1)*128;
*dulout++ = (temp[1]+1)*128;
*dulout++ = (temp[2]+1)*128;
*dulout++ = (temp[0]+1)*127;
*dulout++ = (temp[1]+1)*127;
*dulout++ = (temp[2]+1)*127;
}
}
}

View File

@ -7127,6 +7127,128 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"return inp.col * t_lightmap.Sample(s_lightmap, inp.lmtc);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "wireframe",
"!!ver 100 150\n"
"!!permu TESS\n"
"!!permu FRAMEBLEND\n"
"!!permu SKELETAL\n"
"!!permu FOG\n"
"!!cvardf r_tessellation_level=5\n"
"#include \"sys/defs.h\"\n"
//standard shader used for wireframe stuff.
//must support skeletal and 2-way vertex blending or Bad Things Will Happen.
"#ifdef VERTEX_SHADER\n"
"#include \"sys/skeletal.h\"\n"
"#ifdef TESS\n"
"varying vec3 vertex;\n"
"varying vec3 normal;\n"
"#endif\n"
"void main ()\n"
"{\n"
"vec3 n, s, t, w;\n"
"gl_Position = skeletaltransform_wnst(w,n,s,t);\n"
"#ifdef TESS\n"
"normal = n;\n"
"vertex = w;\n"
"#endif\n"
"}\n"
"#endif\n"
"#if defined(TESS_CONTROL_SHADER)\n"
"layout(vertices = 3) out;\n"
"in vec3 vertex[];\n"
"out vec3 t_vertex[];\n"
"in vec3 normal[];\n"
"out vec3 t_normal[];\n"
"void main()\n"
"{\n"
//the control shader needs to pass stuff through
"#define id gl_InvocationID\n"
"t_vertex[id] = vertex[id];\n"
"t_normal[id] = normal[id];\n"
"gl_TessLevelOuter[0] = float(r_tessellation_level);\n"
"gl_TessLevelOuter[1] = float(r_tessellation_level);\n"
"gl_TessLevelOuter[2] = float(r_tessellation_level);\n"
"gl_TessLevelInner[0] = float(r_tessellation_level);\n"
"}\n"
"#endif\n"
"#if defined(TESS_EVALUATION_SHADER)\n"
"layout(triangles) in;\n"
"in vec3 t_vertex[];\n"
"in vec3 t_normal[];\n"
"#define LERP(a) (gl_TessCoord.x*a[0] + gl_TessCoord.y*a[1] + gl_TessCoord.z*a[2])\n"
"void main()\n"
"{\n"
"#define factor 1.0\n"
"vec3 w = LERP(t_vertex);\n"
"vec3 t0 = w - dot(w-t_vertex[0],t_normal[0])*t_normal[0];\n"
"vec3 t1 = w - dot(w-t_vertex[1],t_normal[1])*t_normal[1];\n"
"vec3 t2 = w - dot(w-t_vertex[2],t_normal[2])*t_normal[2];\n"
"w = w*(1.0-factor) + factor*(gl_TessCoord.x*t0+gl_TessCoord.y*t1+gl_TessCoord.z*t2);\n"
"gl_Position = m_modelviewprojection * vec4(w,1.0);\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"#include \"sys/fog.h\"\n"
"void main ()\n"
"{\n"
"gl_FragColor = fog4(vec4(1.0) * e_colourident);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
@ -9654,11 +9776,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#include \"sys/defs.h\"\n"
"#ifndef USE_ARB_SHADOW\n"
//fall back on regular samplers if we must
"#define sampler2DShadow sampler2D\n"
"#endif\n"
//this is the main shader responsible for realtime dlights.
//texture units:
@ -9669,14 +9786,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
//SPOT(projected circle
//CUBESHADOW
"#ifndef r_glsl_pcf\n"
"#error r_glsl_pcf wasnt defined\n"
"#endif\n"
"#if r_glsl_pcf < 1\n"
"#undef r_glsl_pcf\n"
"#define r_glsl_pcf 9\n"
"#endif\n"
"#if 0 && defined(GL_ARB_texture_gather) && defined(PCF) \n"
"#extension GL_ARB_texture_gather : enable\n"
"#endif\n"
@ -9850,115 +9959,25 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#ifdef FRAGMENT_SHADER\n"
"#include \"sys/fog.h\"\n"
"#ifdef PCF\n"
"vec3 ShadowmapCoord(void)\n"
"{\n"
"#ifdef SPOT\n"
//bias it. don't bother figuring out which side or anything, its not needed
//l_projmatrix contains the light's projection matrix so no other magic needed
"return ((vtexprojcoord.xyz-vec3(0.0,0.0,0.015))/vtexprojcoord.w + vec3(1.0, 1.0, 1.0)) * vec3(0.5, 0.5, 0.5);\n"
//#elif defined(CUBESHADOW)
// vec3 shadowcoord = vshadowcoord.xyz / vshadowcoord.w;
// #define dosamp(x,y) shadowCube(s_shadowmap, shadowcoord + vec2(x,y)*texscale.xy).r
"#else\n"
//figure out which axis to use
//texture is arranged thusly:
//forward left up
//back right down
"vec3 dir = abs(vtexprojcoord.xyz);\n"
//assume z is the major axis (ie: forward from the light)
"vec3 t = vtexprojcoord.xyz;\n"
"float ma = dir.z;\n"
"vec3 axis = vec3(0.5/3.0, 0.5/2.0, 0.5);\n"
"if (dir.x > ma)\n"
"{\n"
"ma = dir.x;\n"
"t = vtexprojcoord.zyx;\n"
"axis.x = 0.5;\n"
"}\n"
"if (dir.y > ma)\n"
"{\n"
"ma = dir.y;\n"
"t = vtexprojcoord.xzy;\n"
"axis.x = 2.5/3.0;\n"
"}\n"
//if the axis is negative, flip it.
"if (t.z > 0.0)\n"
"{\n"
"axis.y = 1.5/2.0;\n"
"t.z = -t.z;\n"
"}\n"
//we also need to pass the result through the light's projection matrix too
//the 'matrix' we need only contains 5 actual values. and one of them is a -1. So we might as well just use a vec4.
//note: the projection matrix also includes scalers to pinch the image inwards to avoid sampling over borders, as well as to cope with non-square source image
//the resulting z is prescaled to result in a value between -0.5 and 0.5.
//also make sure we're in the right quadrant type thing
"return axis + ((l_shadowmapproj.xyz*t.xyz + vec3(0.0, 0.0, l_shadowmapproj.w)) / -t.z);\n"
"#endif\n"
"}\n"
"float ShadowmapFilter(void)\n"
"{\n"
"vec3 shadowcoord = ShadowmapCoord();\n"
"#if 0//def GL_ARB_texture_gather\n"
"vec2 ipart, fpart;\n"
"#define dosamp(x,y) textureGatherOffset(s_shadowmap, ipart.xy, vec2(x,y)))\n"
"vec4 tl = step(shadowcoord.z, dosamp(-1.0, -1.0));\n"
"vec4 bl = step(shadowcoord.z, dosamp(-1.0, 1.0));\n"
"vec4 tr = step(shadowcoord.z, dosamp(1.0, -1.0));\n"
"vec4 br = step(shadowcoord.z, dosamp(1.0, 1.0));\n"
//we now have 4*4 results, woo
//we can just average them for 1/16th precision, but that's still limited graduations
//the middle four pixels are 'full strength', but we interpolate the sides to effectively give 3*3
"vec4 col = vec4(tl.ba, tr.ba) + vec4(bl.rg, br.rg) + //middle two rows are full strength\n"
"mix(vec4(tl.rg, tr.rg), vec4(bl.ba, br.ba), fpart.y); //top+bottom rows\n"
"return dot(mix(col.rgb, col.agb, fpart.x), vec3(1.0/9.0)); //blend r+a, gb are mixed because its pretty much free and gives a nicer dot instruction instead of lots of adds.\n"
"#else\n"
"#ifdef USE_ARB_SHADOW\n"
//with arb_shadow, we can benefit from hardware acclerated pcf, for smoother shadows
"#define dosamp(x,y) shadow2D(s_shadowmap, shadowcoord.xyz + (vec3(x,y,0.0)*l_shadowmapscale.xyx))\n"
"#else\n"
//this will probably be a bit blocky.
"#define dosamp(x,y) float(texture2D(s_shadowmap, shadowcoord.xy + (vec2(x,y)*l_shadowmapscale.xy)).r >= shadowcoord.z)\n"
"#endif\n"
"float s = 0.0;\n"
"#if r_glsl_pcf >= 1 && r_glsl_pcf < 5\n"
"s += dosamp(0.0, 0.0);\n"
"return s;\n"
"#elif r_glsl_pcf >= 5 && r_glsl_pcf < 9\n"
"s += dosamp(-1.0, 0.0);\n"
"s += dosamp(0.0, -1.0);\n"
"s += dosamp(0.0, 0.0);\n"
"s += dosamp(0.0, 1.0);\n"
"s += dosamp(1.0, 0.0);\n"
"return s/5.0;\n"
"#else\n"
"s += dosamp(-1.0, -1.0);\n"
"s += dosamp(-1.0, 0.0);\n"
"s += dosamp(-1.0, 1.0);\n"
"s += dosamp(0.0, -1.0);\n"
"s += dosamp(0.0, 0.0);\n"
"s += dosamp(0.0, 1.0);\n"
"s += dosamp(1.0, -1.0);\n"
"s += dosamp(1.0, 0.0);\n"
"s += dosamp(1.0, 1.0);\n"
"return s/9.0;\n"
"#endif\n"
"#endif\n"
"}\n"
"#endif\n"
"#include \"sys/pcf.h\"\n"
"#ifdef OFFSETMAPPING\n"
"#include \"sys/offsetmapping.h\"\n"
"#endif\n"
"void main ()\n"
"{\n"
"float colorscale = max(1.0 - (dot(lightvector, lightvector)/(l_lightradius*l_lightradius)), 0.0);\n"
"#ifdef PCF\n"
/*filter the light by the shadowmap. logically a boolean, but we allow fractions for softer shadows*/
"colorscale *= ShadowmapFilter(s_shadowmap);\n"
"#endif\n"
"#if defined(SPOT)\n"
/*filter the colour by the spotlight. discard anything behind the light so we don't get a mirror image*/
"if (vtexprojcoord.w < 0.0) discard;\n"
"vec2 spot = ((vtexprojcoord.st)/vtexprojcoord.w);\n"
"colorscale*=1.0-(dot(spot,spot));\n"
"#endif\n"
//read raw texture samples (offsetmapping munges the tex coords first)
"#ifdef OFFSETMAPPING\n"
"vec2 tcoffsetmap = offsetmap(s_normalmap, tcbase, eyevector);\n"
@ -9986,7 +10005,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"vec4 specs = texture2D(s_specular, tcbase);\n"
"#endif\n"
"float colorscale = max(1.0 - (dot(lightvector, lightvector)/(l_lightradius*l_lightradius)), 0.0);\n"
"vec3 diff;\n"
"#ifdef NOBUMP\n"
//surface can only support ambient lighting, even for lights that try to avoid it.
@ -10020,19 +10038,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"diff *= textureCube(s_projectionmap, vtexprojcoord.xyz).rgb;\n"
"#endif\n"
"#if defined(SPOT)\n"
/*filter the colour by the spotlight. discard anything behind the light so we don't get a mirror image*/
"if (vtexprojcoord.w < 0.0) discard;\n"
"vec2 spot = ((vtexprojcoord.st)/vtexprojcoord.w);colorscale*=1.0-(dot(spot,spot));\n"
"#endif\n"
"#ifdef PCF\n"
/*filter the light by the shadowmap. logically a boolean, but we allow fractions for softer shadows*/
//diff.rgb = (vtexprojcoord.xyz/vtexprojcoord.w) * 0.5 + 0.5;
"colorscale *= ShadowmapFilter();\n"
// diff = ShadowmapCoord();
"#endif\n"
"#if defined(PROJECTION)\n"
/*2d projection, not used*/
// diff *= texture2d(s_projectionmap, shadowcoord);

View File

@ -24,6 +24,7 @@ char shaders[][64] =
"defaultwarp",
"defaultgammacb",
"drawflat_wall",
"wireframe",
"lpp_depthnorm",
"lpp_light",
"lpp_wall",

View File

@ -13,11 +13,6 @@
#include "sys/defs.h"
#ifndef USE_ARB_SHADOW
//fall back on regular samplers if we must
#define sampler2DShadow sampler2D
#endif
//this is the main shader responsible for realtime dlights.
//texture units:
@ -28,14 +23,6 @@
//SPOT(projected circle
//CUBESHADOW
#ifndef r_glsl_pcf
#error r_glsl_pcf wasnt defined
#endif
#if r_glsl_pcf < 1
#undef r_glsl_pcf
#define r_glsl_pcf 9
#endif
#if 0 && defined(GL_ARB_texture_gather) && defined(PCF)
#extension GL_ARB_texture_gather : enable
#endif
@ -209,115 +196,25 @@ void main()
#ifdef FRAGMENT_SHADER
#include "sys/fog.h"
#ifdef PCF
vec3 ShadowmapCoord(void)
{
#ifdef SPOT
//bias it. don't bother figuring out which side or anything, its not needed
//l_projmatrix contains the light's projection matrix so no other magic needed
return ((vtexprojcoord.xyz-vec3(0.0,0.0,0.015))/vtexprojcoord.w + vec3(1.0, 1.0, 1.0)) * vec3(0.5, 0.5, 0.5);
//#elif defined(CUBESHADOW)
// vec3 shadowcoord = vshadowcoord.xyz / vshadowcoord.w;
// #define dosamp(x,y) shadowCube(s_shadowmap, shadowcoord + vec2(x,y)*texscale.xy).r
#else
//figure out which axis to use
//texture is arranged thusly:
//forward left up
//back right down
vec3 dir = abs(vtexprojcoord.xyz);
//assume z is the major axis (ie: forward from the light)
vec3 t = vtexprojcoord.xyz;
float ma = dir.z;
vec3 axis = vec3(0.5/3.0, 0.5/2.0, 0.5);
if (dir.x > ma)
{
ma = dir.x;
t = vtexprojcoord.zyx;
axis.x = 0.5;
}
if (dir.y > ma)
{
ma = dir.y;
t = vtexprojcoord.xzy;
axis.x = 2.5/3.0;
}
//if the axis is negative, flip it.
if (t.z > 0.0)
{
axis.y = 1.5/2.0;
t.z = -t.z;
}
//we also need to pass the result through the light's projection matrix too
//the 'matrix' we need only contains 5 actual values. and one of them is a -1. So we might as well just use a vec4.
//note: the projection matrix also includes scalers to pinch the image inwards to avoid sampling over borders, as well as to cope with non-square source image
//the resulting z is prescaled to result in a value between -0.5 and 0.5.
//also make sure we're in the right quadrant type thing
return axis + ((l_shadowmapproj.xyz*t.xyz + vec3(0.0, 0.0, l_shadowmapproj.w)) / -t.z);
#endif
}
float ShadowmapFilter(void)
{
vec3 shadowcoord = ShadowmapCoord();
#if 0//def GL_ARB_texture_gather
vec2 ipart, fpart;
#define dosamp(x,y) textureGatherOffset(s_shadowmap, ipart.xy, vec2(x,y)))
vec4 tl = step(shadowcoord.z, dosamp(-1.0, -1.0));
vec4 bl = step(shadowcoord.z, dosamp(-1.0, 1.0));
vec4 tr = step(shadowcoord.z, dosamp(1.0, -1.0));
vec4 br = step(shadowcoord.z, dosamp(1.0, 1.0));
//we now have 4*4 results, woo
//we can just average them for 1/16th precision, but that's still limited graduations
//the middle four pixels are 'full strength', but we interpolate the sides to effectively give 3*3
vec4 col = vec4(tl.ba, tr.ba) + vec4(bl.rg, br.rg) + //middle two rows are full strength
mix(vec4(tl.rg, tr.rg), vec4(bl.ba, br.ba), fpart.y); //top+bottom rows
return dot(mix(col.rgb, col.agb, fpart.x), vec3(1.0/9.0)); //blend r+a, gb are mixed because its pretty much free and gives a nicer dot instruction instead of lots of adds.
#else
#ifdef USE_ARB_SHADOW
//with arb_shadow, we can benefit from hardware acclerated pcf, for smoother shadows
#define dosamp(x,y) shadow2D(s_shadowmap, shadowcoord.xyz + (vec3(x,y,0.0)*l_shadowmapscale.xyx))
#else
//this will probably be a bit blocky.
#define dosamp(x,y) float(texture2D(s_shadowmap, shadowcoord.xy + (vec2(x,y)*l_shadowmapscale.xy)).r >= shadowcoord.z)
#endif
float s = 0.0;
#if r_glsl_pcf >= 1 && r_glsl_pcf < 5
s += dosamp(0.0, 0.0);
return s;
#elif r_glsl_pcf >= 5 && r_glsl_pcf < 9
s += dosamp(-1.0, 0.0);
s += dosamp(0.0, -1.0);
s += dosamp(0.0, 0.0);
s += dosamp(0.0, 1.0);
s += dosamp(1.0, 0.0);
return s/5.0;
#else
s += dosamp(-1.0, -1.0);
s += dosamp(-1.0, 0.0);
s += dosamp(-1.0, 1.0);
s += dosamp(0.0, -1.0);
s += dosamp(0.0, 0.0);
s += dosamp(0.0, 1.0);
s += dosamp(1.0, -1.0);
s += dosamp(1.0, 0.0);
s += dosamp(1.0, 1.0);
return s/9.0;
#endif
#endif
}
#endif
#include "sys/pcf.h"
#ifdef OFFSETMAPPING
#include "sys/offsetmapping.h"
#endif
void main ()
{
float colorscale = max(1.0 - (dot(lightvector, lightvector)/(l_lightradius*l_lightradius)), 0.0);
#ifdef PCF
/*filter the light by the shadowmap. logically a boolean, but we allow fractions for softer shadows*/
colorscale *= ShadowmapFilter(s_shadowmap);
#endif
#if defined(SPOT)
/*filter the colour by the spotlight. discard anything behind the light so we don't get a mirror image*/
if (vtexprojcoord.w < 0.0) discard;
vec2 spot = ((vtexprojcoord.st)/vtexprojcoord.w);
colorscale*=1.0-(dot(spot,spot));
#endif
//read raw texture samples (offsetmapping munges the tex coords first)
#ifdef OFFSETMAPPING
vec2 tcoffsetmap = offsetmap(s_normalmap, tcbase, eyevector);
@ -345,7 +242,6 @@ void main ()
vec4 specs = texture2D(s_specular, tcbase);
#endif
float colorscale = max(1.0 - (dot(lightvector, lightvector)/(l_lightradius*l_lightradius)), 0.0);
vec3 diff;
#ifdef NOBUMP
//surface can only support ambient lighting, even for lights that try to avoid it.
@ -379,19 +275,6 @@ void main ()
diff *= textureCube(s_projectionmap, vtexprojcoord.xyz).rgb;
#endif
#if defined(SPOT)
/*filter the colour by the spotlight. discard anything behind the light so we don't get a mirror image*/
if (vtexprojcoord.w < 0.0) discard;
vec2 spot = ((vtexprojcoord.st)/vtexprojcoord.w);colorscale*=1.0-(dot(spot,spot));
#endif
#ifdef PCF
/*filter the light by the shadowmap. logically a boolean, but we allow fractions for softer shadows*/
//diff.rgb = (vtexprojcoord.xyz/vtexprojcoord.w) * 0.5 + 0.5;
colorscale *= ShadowmapFilter();
// diff = ShadowmapCoord();
#endif
#if defined(PROJECTION)
/*2d projection, not used*/
// diff *= texture2d(s_projectionmap, shadowcoord);

View File

@ -0,0 +1,118 @@
!!ver 100 150
!!permu TESS
!!permu FRAMEBLEND
!!permu SKELETAL
!!permu FOG
!!cvardf r_tessellation_level=5
#include "sys/defs.h"
//standard shader used for wireframe stuff.
//must support skeletal and 2-way vertex blending or Bad Things Will Happen.
#ifdef VERTEX_SHADER
#include "sys/skeletal.h"
#ifdef TESS
varying vec3 vertex;
varying vec3 normal;
#endif
void main ()
{
vec3 n, s, t, w;
gl_Position = skeletaltransform_wnst(w,n,s,t);
#ifdef TESS
normal = n;
vertex = w;
#endif
}
#endif
#if defined(TESS_CONTROL_SHADER)
layout(vertices = 3) out;
in vec3 vertex[];
out vec3 t_vertex[];
in vec3 normal[];
out vec3 t_normal[];
void main()
{
//the control shader needs to pass stuff through
#define id gl_InvocationID
t_vertex[id] = vertex[id];
t_normal[id] = normal[id];
gl_TessLevelOuter[0] = float(r_tessellation_level);
gl_TessLevelOuter[1] = float(r_tessellation_level);
gl_TessLevelOuter[2] = float(r_tessellation_level);
gl_TessLevelInner[0] = float(r_tessellation_level);
}
#endif
#if defined(TESS_EVALUATION_SHADER)
layout(triangles) in;
in vec3 t_vertex[];
in vec3 t_normal[];
#define LERP(a) (gl_TessCoord.x*a[0] + gl_TessCoord.y*a[1] + gl_TessCoord.z*a[2])
void main()
{
#define factor 1.0
vec3 w = LERP(t_vertex);
vec3 t0 = w - dot(w-t_vertex[0],t_normal[0])*t_normal[0];
vec3 t1 = w - dot(w-t_vertex[1],t_normal[1])*t_normal[1];
vec3 t2 = w - dot(w-t_vertex[2],t_normal[2])*t_normal[2];
w = w*(1.0-factor) + factor*(gl_TessCoord.x*t0+gl_TessCoord.y*t1+gl_TessCoord.z*t2);
gl_Position = m_modelviewprojection * vec4(w,1.0);
}
#endif
#ifdef FRAGMENT_SHADER
#include "sys/fog.h"
void main ()
{
gl_FragColor = fog4(vec4(1.0) * e_colourident);
}
#endif