mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-01-19 07:51:03 +00:00
Implement gl3_colorlight, when set to 0, render lights without color
like the (original) software renderer. defaults to 1, of course
This commit is contained in:
parent
187d19215c
commit
cc0eabffed
4 changed files with 108 additions and 3 deletions
|
@ -93,6 +93,7 @@ cvar_t *r_clear;
|
|||
cvar_t *gl3_particle_size;
|
||||
cvar_t *gl3_particle_fade_factor;
|
||||
cvar_t *gl3_particle_square;
|
||||
cvar_t *gl3_colorlight;
|
||||
|
||||
cvar_t *gl_lefthand;
|
||||
cvar_t *r_gunfov;
|
||||
|
@ -210,6 +211,8 @@ GL3_Register(void)
|
|||
gl3_particle_size = ri.Cvar_Get("gl3_particle_size", "40", CVAR_ARCHIVE);
|
||||
gl3_particle_fade_factor = ri.Cvar_Get("gl3_particle_fade_factor", "1.2", CVAR_ARCHIVE);
|
||||
gl3_particle_square = ri.Cvar_Get("gl3_particle_square", "0", CVAR_ARCHIVE);
|
||||
// if set to 0, lights (from lightmaps, dynamic lights and on models) are white instead of colored
|
||||
gl3_colorlight = ri.Cvar_Get("gl3_colorlight", "1", CVAR_ARCHIVE);
|
||||
|
||||
// 0: use lots of calls to glBufferData()
|
||||
// 1: reduce calls to glBufferData() with one big VBO (see GL3_BufferAndDraw3D())
|
||||
|
@ -1746,9 +1749,10 @@ GL3_BeginFrame(float camera_separation)
|
|||
GL3_UpdateUBO3D();
|
||||
}
|
||||
|
||||
if(gl3_particle_square->modified)
|
||||
if(gl3_particle_square->modified || gl3_colorlight->modified)
|
||||
{
|
||||
gl3_particle_square->modified = false;
|
||||
gl3_colorlight->modified = false;
|
||||
GL3_RecreateShaders();
|
||||
}
|
||||
|
||||
|
|
|
@ -161,6 +161,12 @@ DrawAliasFrameLerp(dmdl_t *paliashdr, entity_t* entity, vec3_t shadelight)
|
|||
GL3_UseProgram(gl3state.si3Dalias.shaderProgram);
|
||||
}
|
||||
|
||||
if(gl3_colorlight->value == 0.0f)
|
||||
{
|
||||
float avg = 0.333333f * (shadelight[0]+shadelight[1]+shadelight[2]);
|
||||
shadelight[0] = shadelight[1] = shadelight[2] = avg;
|
||||
}
|
||||
|
||||
/* move should be the delta back to the previous frame * backlerp */
|
||||
VectorSubtract(entity->oldorigin, entity->origin, delta);
|
||||
AngleVectors(entity->angles, vectors[0], vectors[1], vectors[2]);
|
||||
|
|
|
@ -516,6 +516,96 @@ static const char* fragmentSrc3Dlm = MULTILINE_STRING(
|
|||
}
|
||||
);
|
||||
|
||||
static const char* fragmentSrc3DlmNoColor = MULTILINE_STRING(
|
||||
|
||||
// it gets attributes and uniforms from fragmentCommon3D
|
||||
|
||||
struct DynLight { // gl3UniDynLight in C
|
||||
vec3 lightOrigin;
|
||||
float _pad;
|
||||
//vec3 lightColor;
|
||||
//float lightIntensity;
|
||||
vec4 lightColor; // .a is intensity; this way it also works on OSX...
|
||||
// (otherwise lightIntensity always contained 1 there)
|
||||
};
|
||||
|
||||
layout (std140) uniform uniLights
|
||||
{
|
||||
DynLight dynLights[32];
|
||||
uint numDynLights;
|
||||
uint _pad1; uint _pad2; uint _pad3; // FFS, AMD!
|
||||
};
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform sampler2D lightmap0;
|
||||
uniform sampler2D lightmap1;
|
||||
uniform sampler2D lightmap2;
|
||||
uniform sampler2D lightmap3;
|
||||
|
||||
uniform vec4 lmScales[4];
|
||||
|
||||
in vec2 passLMcoord;
|
||||
in vec3 passWorldCoord;
|
||||
in vec3 passNormal;
|
||||
flat in uint passLightFlags;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texel = texture(tex, passTexCoord);
|
||||
|
||||
// apply intensity
|
||||
texel.rgb *= intensity;
|
||||
|
||||
// apply lightmap
|
||||
vec4 lmTex = texture(lightmap0, passLMcoord) * lmScales[0];
|
||||
lmTex += texture(lightmap1, passLMcoord) * lmScales[1];
|
||||
lmTex += texture(lightmap2, passLMcoord) * lmScales[2];
|
||||
lmTex += texture(lightmap3, passLMcoord) * lmScales[3];
|
||||
|
||||
if(passLightFlags != 0u)
|
||||
{
|
||||
// TODO: or is hardcoding 32 better?
|
||||
for(uint i=0u; i<numDynLights; ++i)
|
||||
{
|
||||
// I made the following up, it's probably not too cool..
|
||||
// it basically checks if the light is on the right side of the surface
|
||||
// and, if it is, sets intensity according to distance between light and pixel on surface
|
||||
|
||||
// dyn light number i does not affect this plane, just skip it
|
||||
if((passLightFlags & (1u << i)) == 0u) continue;
|
||||
|
||||
float intens = dynLights[i].lightColor.a;
|
||||
|
||||
vec3 lightToPos = dynLights[i].lightOrigin - passWorldCoord;
|
||||
float distLightToPos = length(lightToPos);
|
||||
float fact = max(0, intens - distLightToPos - 52);
|
||||
|
||||
// move the light source a bit further above the surface
|
||||
// => helps if the lightsource is so close to the surface (e.g. grenades, rockets)
|
||||
// that the dot product below would return 0
|
||||
// (light sources that are below the surface are filtered out by lightFlags)
|
||||
lightToPos += passNormal*32.0;
|
||||
|
||||
// also factor in angle between light and point on surface
|
||||
fact *= max(0, dot(passNormal, normalize(lightToPos)));
|
||||
|
||||
|
||||
lmTex.rgb += dynLights[i].lightColor.rgb * fact * (1.0/256.0);
|
||||
}
|
||||
}
|
||||
|
||||
// turn lightcolor into grey for gl3_colorlight 0
|
||||
lmTex.rgb = vec3(0.333 * (lmTex.r+lmTex.g+lmTex.b));
|
||||
|
||||
lmTex.rgb *= overbrightbits;
|
||||
outColor = lmTex*texel;
|
||||
outColor.rgb = pow(outColor.rgb, vec3(gamma)); // apply gamma correction to result
|
||||
|
||||
outColor.a = 1; // lightmaps aren't used with translucent surfaces
|
||||
}
|
||||
);
|
||||
|
||||
static const char* fragmentSrc3Dcolor = MULTILINE_STRING(
|
||||
|
||||
// it gets attributes and uniforms from fragmentCommon3D
|
||||
|
@ -1011,7 +1101,11 @@ static qboolean createShaders(void)
|
|||
R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for color-only 2D rendering!\n");
|
||||
return false;
|
||||
}
|
||||
if(!initShader3D(&gl3state.si3Dlm, vertexSrc3Dlm, fragmentSrc3Dlm))
|
||||
|
||||
const char* lightmappedFrag = (gl3_colorlight->value == 0.0f)
|
||||
? fragmentSrc3DlmNoColor : fragmentSrc3Dlm;
|
||||
|
||||
if(!initShader3D(&gl3state.si3Dlm, vertexSrc3Dlm, lightmappedFrag))
|
||||
{
|
||||
R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for textured 3D rendering with lightmap!\n");
|
||||
return false;
|
||||
|
@ -1038,7 +1132,7 @@ static qboolean createShaders(void)
|
|||
R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for water rendering!\n");
|
||||
return false;
|
||||
}
|
||||
if(!initShader3D(&gl3state.si3DlmFlow, vertexSrc3DlmFlow, fragmentSrc3Dlm))
|
||||
if(!initShader3D(&gl3state.si3DlmFlow, vertexSrc3DlmFlow, lightmappedFrag))
|
||||
{
|
||||
R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for scrolling textured 3D rendering with lightmap!\n");
|
||||
return false;
|
||||
|
|
|
@ -515,6 +515,7 @@ extern cvar_t *r_lightlevel;
|
|||
extern cvar_t *gl3_overbrightbits;
|
||||
extern cvar_t *gl3_particle_fade_factor;
|
||||
extern cvar_t *gl3_particle_square;
|
||||
extern cvar_t *gl3_colorlight;
|
||||
|
||||
extern cvar_t *r_modulate;
|
||||
extern cvar_t *gl_lightmap;
|
||||
|
|
Loading…
Reference in a new issue