Spotlights.

git-svn-id: https://svn.eduke32.com/eduke32@1266 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
plagman 2009-03-25 19:48:27 +00:00
parent 53bbdc9cd7
commit bd69a9a286
2 changed files with 83 additions and 8 deletions

View file

@ -4,11 +4,14 @@
// o there's also the texture alignment problem Hunter reported (san andreas fault)
// o also sliding doors are still fucked up sometimes (like under the bar in E1L2)
// o shading needs a lot of work
// o remove all the IM matrix crap and write real functions now that it works
// o planeinfrustum
// o RTT portals (water)
// o clip mirrors/portals to their planes
// o merge mirrors/portals from the same plane
// - SPRITES
// o sprite panning
// - SKIES
// o figure a better way to handle ART skies - maybe add symetric caps that would fade to black like a big gem or something wow this is a long column lol ;0)
// o skyview
// - MDSPRITES
// o need full translation and rotation support from CON to attach to game world or tags
//
@ -51,6 +54,7 @@ typedef enum {
PR_BIT_DIFFUSE_MODULATION,
PR_BIT_DIFFUSE_MIRROR_MAP,
PR_BIT_DIFFUSE_GLOW_MAP,
PR_BIT_SPOT_LIGHT,
PR_BIT_POINT_LIGHT,
PR_BIT_FOOTER, // must be just before last
PR_BIT_COUNT // must be last
@ -98,6 +102,9 @@ typedef struct s_prrograminfo {
GLint uniform_mirrorMap;
// PR_BIT_DIFFUSE_GLOW_MAP
GLint uniform_glowMap;
// PR_BIT_SPOT_LIGHT
GLint uniform_spotDir;
GLint uniform_spotRadius;
// PR_BIT_POINT_LIGHT
// GLint uniform_lightCount;
} _prprograminfo;
@ -126,7 +133,7 @@ typedef enum {
typedef struct s_prlight {
int32_t x, y, z, horiz, range;
int16_t angle, sector;
int16_t angle, faderadius, radius, sector;
char color[3];
prlighttype type;
} _prlight;

View file

@ -288,6 +288,22 @@ _prprogrambit prprogrambits[PR_BIT_COUNT] = {
" result = vec4((result.rgb * (1.0 - glowTexel.a)) + (glowTexel.rgb * glowTexel.a), result.a);\n"
"\n",
},
{
1 << PR_BIT_SPOT_LIGHT,
// vert_def
"",
// vert_prog
"",
// frag_def
"uniform vec3 spotDir;\n"
"uniform vec2 spotRadius;\n"
"\n",
// frag_prog
" spotVector = spotDir;\n"
" spotCosRadius = spotRadius;\n"
" isSpotLight = 1;\n"
"\n",
},
{
1 << PR_BIT_POINT_LIGHT,
// vert_def
@ -319,10 +335,12 @@ _prprogrambit prprogrambits[PR_BIT_COUNT] = {
" vec2 lightRange;\n"
" float pointLightDistance;\n"
" float lightAttenuation;\n"
" vec3 N, L, E, R;\n"
" float spotAttenuation;\n"
" vec3 N, L, E, R, D;\n"
" vec3 lightDiffuse;\n"
" float lightSpecular;\n"
" float NdotL;\n"
" float spotCosAngle;\n"
"\n"
" L = normalize(lightVector);\n"
"\n"
@ -331,6 +349,13 @@ _prprogrambit prprogrambits[PR_BIT_COUNT] = {
" lightRange.y = gl_LightSource[0].linearAttenuation;\n"
"\n"
" lightAttenuation = clamp(1.0 - pointLightDistance * lightRange.y, 0.0, 1.0);\n"
" spotAttenuation = 1.0;\n"
"\n"
" if (isSpotLight == 1) {\n"
" D = normalize(spotVector);\n"
" spotCosAngle = dot(-L, D);\n"
" spotAttenuation = clamp((spotCosAngle - spotCosRadius.x) * spotCosRadius.y, 0.0, 1.0);\n"
" }\n"
"\n"
" if (isNormalMapped == 1) {\n"
" N = 2.0 * (normalTexel.rgb - 0.5);\n"
@ -343,7 +368,7 @@ _prprogrambit prprogrambits[PR_BIT_COUNT] = {
" R = reflect(-L, N);\n"
"\n"
" lightDiffuse = diffuseTexel.a * gl_Color.a * diffuseTexel.rgb *\n"
" gl_LightSource[0].diffuse.rgb * lightAttenuation;\n"
" gl_LightSource[0].diffuse.rgb * lightAttenuation * spotAttenuation;\n"
" result += vec4(lightDiffuse * NdotL, 0.0);\n"
"\n"
" lightSpecular = pow( max(dot(R, E), 0.0), 60.0) * 10.0;\n"
@ -374,6 +399,9 @@ _prprogrambit prprogrambits[PR_BIT_COUNT] = {
" int isLightingPass = 0;\n"
" int isNormalMapped = 0;\n"
" mat3 TBN;\n"
" int isSpotLight = 0;\n"
" vec3 spotVector;\n"
" vec2 spotCosRadius;\n"
"\n",
// frag_prog
" gl_FragColor = result;\n"
@ -2727,7 +2755,7 @@ static void polymer_drawmdsprite(spritetype *tspr)
lpos[1] = -prlights[i].z / 16.0f;
lpos[2] = -prlights[i].x;
polymer_transformpoint(lpos, tlpos, curmodelviewmatrix);
polymer_transformpoint(lpos, tlpos, rootmodelviewmatrix);
vec[0] = tlpos[0] - tspos[0];
vec[0] *= vec[0];
@ -3046,8 +3074,12 @@ static int32_t polymer_bindmaterial(_prmaterial material, char* lights, int
programbits |= prprogrambits[PR_BIT_DIFFUSE_GLOW_MAP].bit;
// PR_BIT_POINT_LIGHT
if (lightcount)
if (lightcount) {
programbits |= prprogrambits[PR_BIT_POINT_LIGHT].bit;
// PR_BIT_SPOT_LIGHT
if (prlights[lights[curlight]].radius)
programbits |= prprogrambits[PR_BIT_SPOT_LIGHT].bit;
}
// material override
programbits &= overridematerial;
@ -3166,7 +3198,36 @@ static int32_t polymer_bindmaterial(_prmaterial material, char* lights, int
inpos[1] = -prlights[lights[curlight]].z / 16.0f;
inpos[2] = -prlights[lights[curlight]].x;
polymer_transformpoint(inpos, pos, curmodelviewmatrix);
polymer_transformpoint(inpos, pos, rootmodelviewmatrix);
// PR_BIT_SPOT_LIGHT
if (programbits & prprogrambits[PR_BIT_SPOT_LIGHT].bit)
{
float sinang, cosang, sinhorizang, coshorizangs;
float indir[3], dir[3];
cosang = (float)(sintable[(-prlights[lights[curlight]].angle+1024)&2047]) / 16383.0f;
sinang = (float)(sintable[(-prlights[lights[curlight]].angle+512)&2047]) / 16383.0f;
coshorizangs = (float)(sintable[(getangle(128, prlights[lights[curlight]].horiz-100)+1024)&2047]) / 16383.0f;
sinhorizang = (float)(sintable[(getangle(128, prlights[lights[curlight]].horiz-100)+512)&2047]) / 16383.0f;
indir[0] = inpos[0] + sinhorizang * cosang;
indir[1] = inpos[1] - coshorizangs;
indir[2] = inpos[2] - sinhorizang * sinang;
polymer_transformpoint(indir, dir, rootmodelviewmatrix);
dir[0] -= pos[0];
dir[1] -= pos[1];
dir[2] -= pos[2];
indir[0] = (float)(sintable[(prlights[lights[curlight]].radius+512)&2047]) / 16383.0f;
indir[1] = (float)(sintable[(prlights[lights[curlight]].faderadius+512)&2047]) / 16383.0f;
indir[1] = 1.0 / (indir[1] - indir[0]);
bglUniform3fvARB(prprograms[programbits].uniform_spotDir, 1, dir);
bglUniform2fvARB(prprograms[programbits].uniform_spotRadius, 1, indir);
}
range[0] = prlights[lights[curlight]].range / 1000.0f;
range[1] = 1 / range[0];
@ -3324,6 +3385,13 @@ static void polymer_compileprogram(int32_t programbits)
prprograms[programbits].uniform_glowMap = bglGetUniformLocationARB(program, "glowMap");
}
// PR_BIT_SPOT_LIGHT
if (programbits & prprogrambits[PR_BIT_SPOT_LIGHT].bit)
{
prprograms[programbits].uniform_spotDir = bglGetUniformLocationARB(program, "spotDir");
prprograms[programbits].uniform_spotRadius = bglGetUniformLocationARB(program, "spotRadius");
}
// PR_BIT_POINT_LIGHT
if (programbits & prprogrambits[PR_BIT_POINT_LIGHT].bit && glinfo.sm4)
{