mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
Further cleanup of lighting code.
- remove thing color from lighting calculations. - implement alpha textures and inverse sprites for infrared as texture modes. This still requires some handling for the alpha texture mode for non-shader rendering because there is no way in the fixed pipeline to do it. The inverted texture effect can be done with a texture combiner. - fixed: ThingColor for sprites was set in the wrong place. It must be in the Process function, not in the lighting calculation. - added functions for isolated calculation of sprites' dynlight color.
This commit is contained in:
parent
607be91c48
commit
7793bbbcc9
11 changed files with 133 additions and 72 deletions
|
@ -160,13 +160,17 @@ void gl_GetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend
|
|||
int blendequation = renderops[style.BlendOp&15];
|
||||
int texturemode = drawopaque? TM_OPAQUE : TM_MODULATE;
|
||||
|
||||
if (style.Flags & STYLEF_ColorIsFixed)
|
||||
if (style.Flags & STYLEF_RedIsAlpha)
|
||||
{
|
||||
texturemode = TM_REDTOALPHA;
|
||||
}
|
||||
else if (style.Flags & STYLEF_ColorIsFixed)
|
||||
{
|
||||
texturemode = TM_MASK;
|
||||
}
|
||||
else if (style.Flags & STYLEF_InvertSource)
|
||||
{
|
||||
texturemode = drawopaque? TM_INVERTOPAQUE : TM_INVERT;
|
||||
texturemode = TM_INVERSE;
|
||||
}
|
||||
|
||||
if (blendequation == -1)
|
||||
|
@ -316,14 +320,9 @@ void gl_GetLightColor(int lightlevel, int rellight, const FColormap * cm, float
|
|||
// set current light color
|
||||
//
|
||||
//==========================================================================
|
||||
void gl_SetColor(int light, int rellight, const FColormap * cm, float *red, float *green, float *blue, PalEntry ThingColor, bool weapon)
|
||||
void gl_SetColor(int light, int rellight, const FColormap * cm, float *red, float *green, float *blue, bool weapon)
|
||||
{
|
||||
float r,g,b;
|
||||
gl_GetLightColor(light, rellight, cm, &r, &g, &b, weapon);
|
||||
|
||||
*red = r * ThingColor.r/255.0f;
|
||||
*green = g * ThingColor.g/255.0f;
|
||||
*blue = b * ThingColor.b/255.0f;
|
||||
gl_GetLightColor(light, rellight, cm, red, green, blue, weapon);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -331,20 +330,15 @@ void gl_SetColor(int light, int rellight, const FColormap * cm, float *red, floa
|
|||
// set current light color
|
||||
//
|
||||
//==========================================================================
|
||||
void gl_SetColor(int light, int rellight, const FColormap * cm, float alpha, PalEntry ThingColor, bool weapon)
|
||||
void gl_SetColor(int light, int rellight, const FColormap * cm, float alpha, bool weapon)
|
||||
{
|
||||
float r,g,b;
|
||||
|
||||
gl_GetLightColor(light, rellight, cm, &r, &g, &b, weapon);
|
||||
|
||||
if (glset.lightmode != 8)
|
||||
{
|
||||
glColor4f(r * ThingColor.r/255.0f, g * ThingColor.g/255.0f, b * ThingColor.b/255.0f, alpha);
|
||||
}
|
||||
else
|
||||
gl_RenderState.SetColor(r, g, b, alpha);
|
||||
if (glset.lightmode == 8)
|
||||
{
|
||||
glColor4f(r, g, b, alpha);
|
||||
|
||||
if (gl_fixedcolormap)
|
||||
{
|
||||
glVertexAttrib1f(VATTR_LIGHTLEVEL, 1.0);
|
||||
|
|
|
@ -20,8 +20,7 @@ void gl_SetFogParams(int _fogdensity, PalEntry _outsidefogcolor, int _outsidefog
|
|||
int gl_CalcLightLevel(int lightlevel, int rellight, bool weapon);
|
||||
PalEntry gl_CalcLightColor(int light, PalEntry pe, int blendfactor, bool force = false);
|
||||
void gl_GetLightColor(int lightlevel, int rellight, const FColormap * cm, float * pred, float * pgreen, float * pblue, bool weapon=false);
|
||||
void gl_SetColor(int light, int rellight, const FColormap * cm, float alpha, PalEntry ThingColor = 0xffffff, bool weapon=false);
|
||||
void gl_SetColor(int light, int rellight, const FColormap * cm, float *red, float *green, float *blue, PalEntry ThingColor=0xffffff, bool weapon=false);
|
||||
void gl_SetColor(int light, int rellight, const FColormap * cm, float alpha, bool weapon=false);
|
||||
|
||||
float gl_GetFogDensity(int lightlevel, PalEntry fogcolor);
|
||||
struct sector_t;
|
||||
|
|
|
@ -338,6 +338,7 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms)
|
|||
else
|
||||
{
|
||||
// This is an alpha texture
|
||||
gl_RenderState.SetTextureMode(TM_REDTOALPHA);
|
||||
gltex->BindPatch(CM_SHADE, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -377,7 +377,7 @@ void GLWall::DrawDecal(DBaseDecal *decal)
|
|||
{
|
||||
if (glset.lightmode == 8)
|
||||
{
|
||||
gl_SetColor(light, rel, &p, a, extralight); // Korshun.
|
||||
gl_SetColor(light, rel, &p, a, !!extralight); // Korshun.
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -169,7 +169,7 @@ void GLSprite::Draw(int pass)
|
|||
}
|
||||
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL,minalpha*gl_mask_sprite_threshold);
|
||||
glColor4f(0.2f,0.2f,0.2f,fuzzalpha);
|
||||
gl_RenderState.SetColor(0.2f,0.2f,0.2f,fuzzalpha);
|
||||
additivefog = true;
|
||||
}
|
||||
else if (RenderStyle.BlendOp == STYLEOP_Add && RenderStyle.DestAlpha == STYLEALPHA_One)
|
||||
|
@ -181,22 +181,23 @@ void GLSprite::Draw(int pass)
|
|||
{
|
||||
if (actor)
|
||||
{
|
||||
lightlevel = gl_SetSpriteLighting(RenderStyle, actor, lightlevel, rel, &Colormap, ThingColor, trans,
|
||||
lightlevel = gl_SetSpriteLighting(RenderStyle, actor, lightlevel, rel, &Colormap, 0xffffffff, trans,
|
||||
fullbright || gl_fixedcolormap >= CM_FIRSTSPECIALCOLORMAP, false);
|
||||
}
|
||||
else if (particle)
|
||||
{
|
||||
if (gl_light_particles)
|
||||
{
|
||||
lightlevel = gl_SetSpriteLight(particle, lightlevel, rel, &Colormap, trans, ThingColor);
|
||||
lightlevel = gl_SetSpriteLight(particle, lightlevel, rel, &Colormap, trans, 0xffffffff);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_SetColor(lightlevel, rel, &Colormap, trans, ThingColor);
|
||||
gl_SetColor(lightlevel, rel, &Colormap, trans);
|
||||
}
|
||||
}
|
||||
else return;
|
||||
}
|
||||
gl_RenderState.SetObjectColor(ThingColor);
|
||||
|
||||
if (gl_isBlack(Colormap.FadeColor)) foglevel=lightlevel;
|
||||
|
||||
|
@ -425,13 +426,6 @@ void GLSprite::SplitSprite(sector_t * frontsector, bool translucent)
|
|||
copySprite.Colormap.LightColor.b=(255+v+v)/3;
|
||||
}
|
||||
|
||||
if (!gl_isWhite(ThingColor))
|
||||
{
|
||||
copySprite.Colormap.LightColor.r=(copySprite.Colormap.LightColor.r*ThingColor.r)>>8;
|
||||
copySprite.Colormap.LightColor.g=(copySprite.Colormap.LightColor.g*ThingColor.g)>>8;
|
||||
copySprite.Colormap.LightColor.b=(copySprite.Colormap.LightColor.b*ThingColor.b)>>8;
|
||||
}
|
||||
|
||||
z1=copySprite.z2=maplightbottom;
|
||||
vt=copySprite.vb=copySprite.vt+
|
||||
(maplightbottom-copySprite.z1)*(copySprite.vb-copySprite.vt)/(z2-copySprite.z1);
|
||||
|
@ -471,13 +465,6 @@ void GLSprite::SetSpriteColor(sector_t *sector, fixed_t center_y)
|
|||
Colormap.LightColor.g=
|
||||
Colormap.LightColor.b=(255+v+v)/3;
|
||||
}
|
||||
|
||||
if (!gl_isWhite(ThingColor))
|
||||
{
|
||||
Colormap.LightColor.r=(Colormap.LightColor.r*ThingColor.r)>>8;
|
||||
Colormap.LightColor.g=(Colormap.LightColor.g*ThingColor.g)>>8;
|
||||
Colormap.LightColor.b=(Colormap.LightColor.b*ThingColor.b)>>8;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -734,6 +721,10 @@ void GLSprite::Process(AActor* thing,sector_t * sector)
|
|||
|
||||
lightlevel = (byte)gl_CheckSpriteGlow(rendersector, lightlevel, thingx, thingy, thingz);
|
||||
|
||||
ThingColor = (thing->RenderStyle.Flags & STYLEF_ColorIsFixed) ? thing->fillcolor : 0xffffff;
|
||||
ThingColor.a = 255;
|
||||
RenderStyle = thing->RenderStyle;
|
||||
|
||||
// colormap stuff is a little more complicated here...
|
||||
if (gl_fixedcolormap)
|
||||
{
|
||||
|
@ -749,8 +740,7 @@ void GLSprite::Process(AActor* thing,sector_t * sector)
|
|||
if (gl_enhanced_nightvision &&
|
||||
(thing->IsKindOf(RUNTIME_CLASS(AInventory)) || thing->flags3&MF3_ISMONSTER || thing->flags&MF_MISSILE || thing->flags&MF_CORPSE))
|
||||
{
|
||||
// needs to be fixed later
|
||||
//Colormap.colormap = CM_FIRSTSPECIALCOLORMAP + INVERSECOLORMAP;
|
||||
RenderStyle.Flags |= STYLEF_InvertSource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -785,8 +775,6 @@ void GLSprite::Process(AActor* thing,sector_t * sector)
|
|||
|
||||
translation=thing->Translation;
|
||||
|
||||
ThingColor=0xffffff;
|
||||
RenderStyle = thing->RenderStyle;
|
||||
OverrideShader = 0;
|
||||
trans = FIXED2FLOAT(thing->alpha);
|
||||
hw_styleflags = STYLEHW_Normal;
|
||||
|
@ -955,8 +943,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
|
|||
OverrideShader = 0;
|
||||
|
||||
ThingColor = particle->color;
|
||||
gl_ModifyColor(ThingColor.r, ThingColor.g, ThingColor.b, Colormap.colormap);
|
||||
ThingColor.a=0;
|
||||
ThingColor.a = 255;
|
||||
|
||||
modelframe=NULL;
|
||||
gltexture=NULL;
|
||||
|
|
|
@ -57,6 +57,77 @@
|
|||
#include "gl/textures/gl_material.h"
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets a single light value from all dynamic lights affecting the specified location
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void gl_SetDynSpriteLight(AActor *self, fixed_t x, fixed_t y, fixed_t z, subsector_t * subsec)
|
||||
{
|
||||
ADynamicLight *light;
|
||||
float frac, lr, lg, lb;
|
||||
float radius;
|
||||
float out[3] = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
// Go through both light lists
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
FLightNode * node = subsec->lighthead[i];
|
||||
while (node)
|
||||
{
|
||||
light = node->lightsource;
|
||||
if (!light->owned || light->target == NULL || light->target->IsVisibleToPlayer())
|
||||
{
|
||||
if (!(light->flags2&MF2_DORMANT) &&
|
||||
(!(light->flags4&MF4_DONTLIGHTSELF) || light->target != self))
|
||||
{
|
||||
float dist = FVector3(FIXED2FLOAT(x - light->x), FIXED2FLOAT(y - light->y), FIXED2FLOAT(z - light->z)).Length();
|
||||
radius = light->GetRadius() * gl_lights_size;
|
||||
|
||||
if (dist < radius)
|
||||
{
|
||||
frac = 1.0f - (dist / radius);
|
||||
|
||||
if (frac > 0)
|
||||
{
|
||||
lr = light->GetRed() / 255.0f * gl_lights_intensity;
|
||||
lg = light->GetGreen() / 255.0f * gl_lights_intensity;
|
||||
lb = light->GetBlue() / 255.0f * gl_lights_intensity;
|
||||
if (light->IsSubtractive())
|
||||
{
|
||||
float bright = FVector3(lr, lg, lb).Length();
|
||||
FVector3 lightColor(lr, lg, lb);
|
||||
lr = (bright - lr) * -1;
|
||||
lg = (bright - lg) * -1;
|
||||
lb = (bright - lb) * -1;
|
||||
}
|
||||
|
||||
out[0] += lr * frac;
|
||||
out[1] += lg * frac;
|
||||
out[2] += lb * frac;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node = node->nextLight;
|
||||
}
|
||||
}
|
||||
gl_RenderState.SetDynLight(out[0], out[1], out[2]);
|
||||
}
|
||||
|
||||
void gl_SetDynSpriteLight(AActor *thing, particle_t *particle)
|
||||
{
|
||||
if (thing != NULL)
|
||||
{
|
||||
gl_SetDynSpriteLight(thing, thing->x, thing->y, thing->z + (thing->height >> 1), thing->subsector);
|
||||
}
|
||||
else if (particle != NULL)
|
||||
{
|
||||
gl_SetDynSpriteLight(NULL, particle->x, particle->y, particle->z, particle->subsector);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Gets the light for a sprite - takes dynamic lights into account
|
||||
|
@ -294,7 +365,7 @@ int gl_SetSpriteLighting(FRenderStyle style, AActor *thing, int lightlevel, int
|
|||
}
|
||||
else
|
||||
{
|
||||
gl_SetColor(lightlevel, rellight, cm, alpha, ThingColor, weapon);
|
||||
gl_SetColor(lightlevel, rellight, cm, alpha, weapon);
|
||||
}
|
||||
}
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL,alpha*gl_mask_sprite_threshold);
|
||||
|
|
|
@ -351,6 +351,10 @@ inline float Dist2(float x1,float y1,float x2,float y2)
|
|||
|
||||
// Light + color
|
||||
|
||||
void gl_SetDynSpriteLight(AActor *self, fixed_t x, fixed_t y, fixed_t z, subsector_t *subsec);
|
||||
void gl_SetDynSpriteLight(AActor *actor, particle_t *particle);
|
||||
|
||||
|
||||
bool gl_GetSpriteLight(AActor *Self, fixed_t x, fixed_t y, fixed_t z, subsector_t * subsec, int desaturation, float * out, line_t *line = NULL, int side = 0);
|
||||
int gl_SetSpriteLight(AActor * thing, int lightlevel, int rellight, FColormap * cm, float alpha, PalEntry ThingColor = 0xffffff, bool weapon=false);
|
||||
|
||||
|
|
|
@ -194,8 +194,7 @@ void gl_PrintStartupLog()
|
|||
|
||||
void gl_SetTextureMode(int type)
|
||||
{
|
||||
static float white[] = {1.f,1.f,1.f,1.f};
|
||||
|
||||
gl.needAlphaTexture = false;
|
||||
if (type == TM_MASK)
|
||||
{
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
|
@ -222,7 +221,7 @@ void gl_SetTextureMode(int type)
|
|||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
|
||||
}
|
||||
else if (type == TM_INVERT)
|
||||
else if (type == TM_INVERSE)
|
||||
{
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
|
||||
|
@ -237,22 +236,10 @@ void gl_SetTextureMode(int type)
|
|||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
|
||||
}
|
||||
else if (type == TM_INVERTOPAQUE)
|
||||
{
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_ONE_MINUS_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
|
||||
}
|
||||
else // if (type == TM_MODULATE)
|
||||
{
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
gl.needAlphaTexture = (type == TM_REDTOALPHA);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,16 +16,13 @@ enum RenderFlags
|
|||
|
||||
enum TexMode
|
||||
{
|
||||
TMF_MASKBIT = 1,
|
||||
TMF_OPAQUEBIT = 2,
|
||||
TMF_INVERTBIT = 4,
|
||||
TM_MODULATE = 0, // (r, g, b, a)
|
||||
TM_MASK = 1, // (1, 1, 1, a)
|
||||
TM_OPAQUE = 2, // (r, g, b, 1)
|
||||
TM_INVERSE = 3, // (1-r, 1-g, 1-b, a)
|
||||
TM_REDTOALPHA = 4, // (1, 1, 1, r)
|
||||
|
||||
TM_MODULATE = 0,
|
||||
TM_MASK = TMF_MASKBIT,
|
||||
TM_OPAQUE = TMF_OPAQUEBIT,
|
||||
TM_INVERT = TMF_INVERTBIT,
|
||||
//TM_INVERTMASK = TMF_MASKBIT | TMF_INVERTBIT
|
||||
TM_INVERTOPAQUE = TMF_INVERTBIT | TMF_OPAQUEBIT,
|
||||
// 4 cannot be done natively without shaders and requires special textures.
|
||||
};
|
||||
|
||||
struct RenderContext
|
||||
|
@ -36,6 +33,7 @@ struct RenderContext
|
|||
float glslversion;
|
||||
int max_texturesize;
|
||||
char * vendorstring;
|
||||
bool needAlphaTexture;
|
||||
|
||||
int MaxLights() const
|
||||
{
|
||||
|
|
|
@ -149,7 +149,17 @@ vec4 getTexel(vec2 st)
|
|||
//
|
||||
// Apply texture modes
|
||||
//
|
||||
if (texturemode == 2)
|
||||
if (texturemode == 3)
|
||||
{
|
||||
texel *=objectcolor;
|
||||
texel = vec4(1.0-texel.r, 1.0-texel.g, 1.0-texel.b, texel.a);
|
||||
return texel;
|
||||
}
|
||||
else if (texturemode == 4)
|
||||
{
|
||||
texel = vec4(1.0, 1.0, 1.0, texel.r);
|
||||
}
|
||||
else if (texturemode == 2)
|
||||
{
|
||||
texel.a = 1.0;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,17 @@ vec4 getTexel(vec2 st)
|
|||
//
|
||||
// Apply texture modes
|
||||
//
|
||||
if (texturemode == 2)
|
||||
if (texturemode == 3)
|
||||
{
|
||||
texel *=objectcolor;
|
||||
texel = vec4(1.0-texel.r, 1.0-texel.g, 1.0-texel.b, texel.a);
|
||||
return texel;
|
||||
}
|
||||
else if (texturemode == 4)
|
||||
{
|
||||
texel = vec4(1.0, 1.0, 1.0, texel.r);
|
||||
}
|
||||
else if (texturemode == 2)
|
||||
{
|
||||
texel.a = 1.0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue