diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index afd5cdbcf..102d1d43e 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -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); diff --git a/src/gl/renderer/gl_lightdata.h b/src/gl/renderer/gl_lightdata.h index 33d179b27..8eb70bbb9 100644 --- a/src/gl/renderer/gl_lightdata.h +++ b/src/gl/renderer/gl_lightdata.h @@ -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; diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 3ce805351..5120c00ea 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -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); } diff --git a/src/gl/scene/gl_decal.cpp b/src/gl/scene/gl_decal.cpp index bd39f8008..959641076 100644 --- a/src/gl/scene/gl_decal.cpp +++ b/src/gl/scene/gl_decal.cpp @@ -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 { diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 46541fc27..d64f62b71 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -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; diff --git a/src/gl/scene/gl_spritelight.cpp b/src/gl/scene/gl_spritelight.cpp index b1216d86b..66a2b6c7f 100644 --- a/src/gl/scene/gl_spritelight.cpp +++ b/src/gl/scene/gl_spritelight.cpp @@ -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); diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 207b7bdbf..ba050c1b6 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -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); diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 434659a7c..7615373c5 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -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); } } diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index 66f96be00..13913f621 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -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 { diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 8587b5ac3..d4334251b 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -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; } diff --git a/wadsrc/static/shaders/glsl/main_colormap.fp b/wadsrc/static/shaders/glsl/main_colormap.fp index d4c079cdd..d78a21f5f 100644 --- a/wadsrc/static/shaders/glsl/main_colormap.fp +++ b/wadsrc/static/shaders/glsl/main_colormap.fp @@ -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; }