mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
- removed texture based dynamic lighting. For GL 3.x the shader approach is always better.
- fixed: sky fog was not unset.
This commit is contained in:
parent
fb6b4238ed
commit
b8bcbe819b
17 changed files with 129 additions and 657 deletions
|
@ -521,14 +521,12 @@ void ADynamicLight::CollectWithinRadius(subsector_t *subSec, float radius)
|
|||
{
|
||||
if (!subSec) return;
|
||||
|
||||
bool additive = (flags4&MF4_ADDITIVE) || gl_lights_additive;
|
||||
|
||||
subSec->validcount = ::validcount;
|
||||
|
||||
touching_subsectors = AddLightNode(&subSec->lighthead[additive], subSec, this, touching_subsectors);
|
||||
touching_subsectors = AddLightNode(&subSec->lighthead, subSec, this, touching_subsectors);
|
||||
if (subSec->sector->validcount != ::validcount)
|
||||
{
|
||||
touching_sector = AddLightNode(&subSec->render_sector->lighthead[additive], subSec->sector, this, touching_sector);
|
||||
touching_sector = AddLightNode(&subSec->render_sector->lighthead, subSec->sector, this, touching_sector);
|
||||
subSec->sector->validcount = ::validcount;
|
||||
}
|
||||
|
||||
|
@ -542,7 +540,7 @@ void ADynamicLight::CollectWithinRadius(subsector_t *subSec, float radius)
|
|||
if (DMulScale32 (y-seg->v1->y, seg->v2->x-seg->v1->x, seg->v1->x-x, seg->v2->y-seg->v1->y) <=0)
|
||||
{
|
||||
seg->linedef->validcount=validcount;
|
||||
touching_sides = AddLightNode(&seg->sidedef->lighthead[additive], seg->sidedef, this, touching_sides);
|
||||
touching_sides = AddLightNode(&seg->sidedef->lighthead, seg->sidedef, this, touching_sides);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -755,22 +753,15 @@ CCMD(listsublights)
|
|||
{
|
||||
subsector_t *sub = &subsectors[i];
|
||||
int lights = 0;
|
||||
int addlights = 0;
|
||||
|
||||
FLightNode * node = sub->lighthead[0];
|
||||
FLightNode * node = sub->lighthead;
|
||||
while (node != NULL)
|
||||
{
|
||||
lights++;
|
||||
node = node->nextLight;
|
||||
}
|
||||
|
||||
node = sub->lighthead[1];
|
||||
while (node != NULL)
|
||||
{
|
||||
addlights++;
|
||||
node = node->nextLight;
|
||||
}
|
||||
Printf(PRINT_LOG, "Subsector %d - %d lights, %d additive lights\n", i, lights, addlights);
|
||||
Printf(PRINT_LOG, "Subsector %d - %d lights\n", i, lights);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -184,8 +184,6 @@ struct FDynLightData
|
|||
|
||||
|
||||
bool gl_GetLight(Plane & p, ADynamicLight * light, bool checkside, bool forceadditive, FDynLightData &data);
|
||||
bool gl_SetupLight(Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right, float & scale, int desaturation, bool checkside=true, bool forceadditive=true);
|
||||
bool gl_SetupLightTexture();
|
||||
void gl_UploadLights(FDynLightData &data);
|
||||
|
||||
|
||||
|
|
|
@ -68,17 +68,6 @@ CUSTOM_CVAR (Bool, gl_lights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOIN
|
|||
else gl_DeleteAllAttachedLights();
|
||||
}
|
||||
|
||||
CUSTOM_CVAR (Bool, gl_dynlight_shader, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
if (gl.maxuniforms < 1024 && !(gl.flags & RFL_SHADER_STORAGE_BUFFER))
|
||||
{
|
||||
self = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CVAR (Bool, gl_attachedlights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
CVAR (Bool, gl_lights_checkside, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
CVAR (Float, gl_lights_intensity, 1.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
|
@ -155,75 +144,6 @@ bool gl_GetLight(Plane & p, ADynamicLight * light, bool checkside, bool forceadd
|
|||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets up the parameters to render one dynamic light onto one plane
|
||||
//
|
||||
//==========================================================================
|
||||
bool gl_SetupLight(Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right,
|
||||
float & scale, int desaturation, bool checkside, bool forceadditive)
|
||||
{
|
||||
Vector fn, pos;
|
||||
|
||||
float x = FIXED2FLOAT(light->x);
|
||||
float y = FIXED2FLOAT(light->y);
|
||||
float z = FIXED2FLOAT(light->z);
|
||||
|
||||
float dist = fabsf(p.DistToPoint(x, z, y));
|
||||
float radius = (light->GetRadius() * gl_lights_size);
|
||||
|
||||
if (radius <= 0.f) return false;
|
||||
if (dist > radius) return false;
|
||||
if (checkside && gl_lights_checkside && p.PointOnSide(x, z, y))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (light->owned && light->target != NULL && !light->target->IsVisibleToPlayer())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
scale = 1.0f / ((2.f * radius) - dist);
|
||||
|
||||
// project light position onto plane (find closest point on plane)
|
||||
|
||||
|
||||
pos.Set(x,z,y);
|
||||
fn=p.Normal();
|
||||
fn.GetRightUp(right, up);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
nearPt = pos + fn * dist;
|
||||
#else
|
||||
Vector tmpVec = fn * dist;
|
||||
nearPt = pos + tmpVec;
|
||||
#endif
|
||||
|
||||
float cs = 1.0f - (dist / radius);
|
||||
if (gl_lights_additive || light->flags4&MF4_ADDITIVE || forceadditive) cs*=0.2f; // otherwise the light gets too strong.
|
||||
float r = light->GetRed() / 255.0f * cs * gl_lights_intensity;
|
||||
float g = light->GetGreen() / 255.0f * cs * gl_lights_intensity;
|
||||
float b = light->GetBlue() / 255.0f * cs * gl_lights_intensity;
|
||||
|
||||
if (light->IsSubtractive())
|
||||
{
|
||||
Vector v;
|
||||
|
||||
gl_RenderState.BlendEquation(GL_FUNC_REVERSE_SUBTRACT);
|
||||
v.Set(r, g, b);
|
||||
r = v.Length() - r;
|
||||
g = v.Length() - g;
|
||||
b = v.Length() - b;
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_RenderState.BlendEquation(GL_FUNC_ADD);
|
||||
}
|
||||
gl_RenderState.SetColor(r, g, b, 1.f, desaturation);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -257,31 +177,3 @@ void gl_UploadLights(FDynLightData &data)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool gl_SetupLightTexture()
|
||||
{
|
||||
|
||||
if (GLRenderer->gllight == NULL) return false;
|
||||
FMaterial * pat = FMaterial::ValidateTexture(GLRenderer->gllight);
|
||||
pat->BindPatch(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
inline fixed_t P_AproxDistance3(fixed_t dx, fixed_t dy, fixed_t dz)
|
||||
{
|
||||
return P_AproxDistance(P_AproxDistance(dx,dy),dz);
|
||||
}
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
|
|||
mSkyVBO = NULL;
|
||||
gl_spriteindex = 0;
|
||||
mShaderManager = NULL;
|
||||
glpart2 = glpart = gllight = mirrortexture = NULL;
|
||||
glpart2 = glpart = mirrortexture = NULL;
|
||||
}
|
||||
|
||||
void FGLRenderer::Initialize()
|
||||
|
@ -104,7 +104,6 @@ void FGLRenderer::Initialize()
|
|||
glpart2 = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/glpart2.png"), FTexture::TEX_MiscPatch);
|
||||
glpart = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/glpart.png"), FTexture::TEX_MiscPatch);
|
||||
mirrortexture = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/mirror.png"), FTexture::TEX_MiscPatch);
|
||||
gllight = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/gllight.png"), FTexture::TEX_MiscPatch);
|
||||
|
||||
mVBO = new FFlatVertexBuffer;
|
||||
mSkyVBO = new FSkyVertexBuffer;
|
||||
|
@ -128,7 +127,6 @@ FGLRenderer::~FGLRenderer()
|
|||
if (glpart2) delete glpart2;
|
||||
if (glpart) delete glpart;
|
||||
if (mirrortexture) delete mirrortexture;
|
||||
if (gllight) delete gllight;
|
||||
if (mFBID != 0) glDeleteFramebuffers(1, &mFBID);
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,6 @@ public:
|
|||
FTexture *glpart2;
|
||||
FTexture *glpart;
|
||||
FTexture *mirrortexture;
|
||||
FTexture *gllight;
|
||||
|
||||
float mSky1Pos, mSky2Pos;
|
||||
|
||||
|
|
|
@ -13,14 +13,6 @@ enum GLDrawItemType
|
|||
|
||||
enum DrawListType
|
||||
{
|
||||
// These are organized so that the various multipass rendering modes
|
||||
// have to be set as few times as possible
|
||||
GLDL_LIGHT,
|
||||
GLDL_LIGHTBRIGHT,
|
||||
GLDL_LIGHTMASKED,
|
||||
GLDL_LIGHTFOG,
|
||||
GLDL_LIGHTFOGMASKED,
|
||||
|
||||
GLDL_PLAIN,
|
||||
GLDL_MASKED,
|
||||
GLDL_FOG,
|
||||
|
@ -30,25 +22,15 @@ enum DrawListType
|
|||
GLDL_TRANSLUCENTBORDER,
|
||||
|
||||
GLDL_TYPES,
|
||||
|
||||
GLDL_FIRSTLIGHT = GLDL_LIGHT,
|
||||
GLDL_LASTLIGHT = GLDL_LIGHTFOGMASKED,
|
||||
GLDL_FIRSTNOLIGHT = GLDL_PLAIN,
|
||||
GLDL_LASTNOLIGHT = GLDL_FOGMASKED,
|
||||
};
|
||||
|
||||
enum Drawpasses
|
||||
{
|
||||
GLPASS_BASE, // Draws the untextured surface only
|
||||
GLPASS_BASE_MASKED, // Draws an untextured surface that is masked by the texture
|
||||
GLPASS_PLAIN, // Draws a texture that isn't affected by dynamic lights with sector light settings
|
||||
GLPASS_LIGHT, // Draws dynamic lights
|
||||
GLPASS_LIGHT_ADDITIVE, // Draws additive dynamic lights
|
||||
GLPASS_TEXTURE, // Draws the texture to be modulated with the light information on the base surface
|
||||
GLPASS_PLAIN, // Main pass without dynamic lights
|
||||
GLPASS_ALL, // Main pass with dynamic lights
|
||||
GLPASS_DECALS, // Draws a decal
|
||||
GLPASS_DECALS_NOFOG,// Draws a decal without setting the fog (used for passes that need a fog layer)
|
||||
GLPASS_TRANSLUCENT, // Draws translucent objects
|
||||
GLPASS_ALL // Everything at once, using shaders for dynamic lights
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -103,68 +103,6 @@ void gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * glte
|
|||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Flats
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass)
|
||||
{
|
||||
Plane p;
|
||||
Vector nearPt, up, right, t1;
|
||||
float scale;
|
||||
unsigned int k;
|
||||
seg_t *v;
|
||||
|
||||
FLightNode * node = sub->lighthead[pass==GLPASS_LIGHT_ADDITIVE];
|
||||
gl_RenderState.Apply();
|
||||
while (node)
|
||||
{
|
||||
ADynamicLight * light = node->lightsource;
|
||||
|
||||
if (light->flags2&MF2_DORMANT)
|
||||
{
|
||||
node=node->nextLight;
|
||||
continue;
|
||||
}
|
||||
iter_dlightf++;
|
||||
|
||||
// we must do the side check here because gl_SetupLight needs the correct plane orientation
|
||||
// which we don't have for Legacy-style 3D-floors
|
||||
fixed_t planeh = plane.plane.ZatPoint(light->x, light->y);
|
||||
if (gl_lights_checkside && ((planeh<light->z && ceiling) || (planeh>light->z && !ceiling)))
|
||||
{
|
||||
node=node->nextLight;
|
||||
continue;
|
||||
}
|
||||
|
||||
p.Set(plane.plane);
|
||||
if (!gl_SetupLight(p, light, nearPt, up, right, scale, Colormap.desaturation, false, foggy))
|
||||
{
|
||||
node=node->nextLight;
|
||||
continue;
|
||||
}
|
||||
draw_dlightf++;
|
||||
gl_RenderState.Apply();
|
||||
|
||||
// Render the light
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
for (k = 0, v = sub->firstline; k < sub->numlines; k++, v++)
|
||||
{
|
||||
vertex_t *vt = v->v1;
|
||||
float zc = plane.plane.ZatPoint(vt->fx, vt->fy) + dz;
|
||||
|
||||
t1.Set(vt->fx, zc, vt->fy);
|
||||
Vector nearToVert = t1 - nearPt;
|
||||
ptr->Set(vt->fx, zc, vt->fy, (nearToVert.Dot(right) * scale) + 0.5f, (nearToVert.Dot(up) * scale) + 0.5f);
|
||||
ptr++;
|
||||
}
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
||||
node = node->nextLight;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -178,9 +116,7 @@ bool GLFlat::SetupSubsectorLights(bool lightsapplied, subsector_t * sub)
|
|||
Plane p;
|
||||
|
||||
lightdata.Clear();
|
||||
for(int i=0;i<2;i++)
|
||||
{
|
||||
FLightNode * node = sub->lighthead[i];
|
||||
FLightNode * node = sub->lighthead;
|
||||
while (node)
|
||||
{
|
||||
ADynamicLight * light = node->lightsource;
|
||||
|
@ -205,7 +141,6 @@ bool GLFlat::SetupSubsectorLights(bool lightsapplied, subsector_t * sub)
|
|||
gl_GetLight(p, light, false, false, lightdata);
|
||||
node = node->nextLight;
|
||||
}
|
||||
}
|
||||
|
||||
int numlights[3];
|
||||
|
||||
|
@ -347,7 +282,6 @@ void GLFlat::DrawSubsectors(int pass, bool istrans)
|
|||
//==========================================================================
|
||||
void GLFlat::Draw(int pass)
|
||||
{
|
||||
int i;
|
||||
int rel = getExtraLight();
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
@ -360,65 +294,15 @@ void GLFlat::Draw(int pass)
|
|||
|
||||
switch (pass)
|
||||
{
|
||||
case GLPASS_BASE:
|
||||
gl_SetColor(lightlevel, rel, Colormap,1.0f);
|
||||
if (!foggy) gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||
DrawSubsectors(pass, false);
|
||||
break;
|
||||
|
||||
case GLPASS_PLAIN: // Single-pass rendering
|
||||
case GLPASS_ALL:
|
||||
case GLPASS_BASE_MASKED:
|
||||
gl_SetColor(lightlevel, rel, Colormap,1.0f);
|
||||
if (!foggy || pass != GLPASS_BASE_MASKED) gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||
// fall through
|
||||
case GLPASS_TEXTURE:
|
||||
{
|
||||
gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||
gltexture->Bind();
|
||||
gl_SetPlaneTextureRotation(&plane, gltexture);
|
||||
DrawSubsectors(pass, false);
|
||||
gl_RenderState.EnableTextureMatrix(false);
|
||||
break;
|
||||
}
|
||||
|
||||
case GLPASS_LIGHT:
|
||||
case GLPASS_LIGHT_ADDITIVE:
|
||||
|
||||
if (!foggy) gl_SetFog((255+lightlevel)>>1, 0, &Colormap, false);
|
||||
else gl_SetFog(lightlevel, 0, &Colormap, true);
|
||||
|
||||
if (sub)
|
||||
{
|
||||
DrawSubsectorLights(sub, pass);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw the subsectors belonging to this sector
|
||||
for (i=0; i<sector->subsectorcount; i++)
|
||||
{
|
||||
subsector_t * sub = sector->subsectors[i];
|
||||
|
||||
if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags)
|
||||
{
|
||||
DrawSubsectorLights(sub, pass);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the subsectors assigned to it due to missing textures
|
||||
if (!(renderflags&SSRF_RENDER3DPLANES))
|
||||
{
|
||||
gl_subsectorrendernode * node = (renderflags&SSRF_RENDERFLOOR)?
|
||||
gl_drawinfo->GetOtherFloorPlanes(sector->sectornum) :
|
||||
gl_drawinfo->GetOtherCeilingPlanes(sector->sectornum);
|
||||
|
||||
while (node)
|
||||
{
|
||||
DrawSubsectorLights(node->sub, pass);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GLPASS_TRANSLUCENT:
|
||||
if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
|
@ -462,38 +346,15 @@ inline void GLFlat::PutFlat(bool fog)
|
|||
}
|
||||
if (renderstyle!=STYLE_Translucent || alpha < 1.f - FLT_EPSILON || fog)
|
||||
{
|
||||
int list = (renderflags&SSRF_RENDER3DPLANES) ? GLDL_TRANSLUCENT : GLDL_TRANSLUCENTBORDER;
|
||||
gl_drawinfo->drawlists[list].AddFlat (this);
|
||||
// translucent 3D floors go into the regular translucent list, translucent portals go into the translucent border list.
|
||||
list = (renderflags&SSRF_RENDER3DPLANES) ? GLDL_TRANSLUCENT : GLDL_TRANSLUCENTBORDER;
|
||||
}
|
||||
else if (gltexture != NULL)
|
||||
{
|
||||
static DrawListType list_indices[2][2][2]={
|
||||
{ { GLDL_PLAIN, GLDL_FOG }, { GLDL_MASKED, GLDL_FOGMASKED } },
|
||||
{ { GLDL_LIGHT, GLDL_LIGHTFOG }, { GLDL_LIGHTMASKED, GLDL_LIGHTFOGMASKED } }
|
||||
};
|
||||
|
||||
bool light = false;
|
||||
bool masked = gltexture->isMasked() && ((renderflags&SSRF_RENDER3DPLANES) || stack);
|
||||
|
||||
if (!gl_fixedcolormap)
|
||||
{
|
||||
foggy = gl_CheckFog(&Colormap, lightlevel) || level.flags&LEVEL_HASFADETABLE;
|
||||
|
||||
if (gl_lights && !gl_dynlight_shader && GLRenderer->mLightCount) // Are lights touching this sector?
|
||||
{
|
||||
for(int i=0;i<sector->subsectorcount;i++) if (sector->subsectors[i]->lighthead[0] != NULL)
|
||||
{
|
||||
light=true;
|
||||
list = masked ? GLDL_MASKED : GLDL_PLAIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
else foggy = false;
|
||||
|
||||
list = list_indices[light][masked][foggy];
|
||||
if (list == GLDL_LIGHT && gltexture->tex->gl_info.Brightmap) list = GLDL_LIGHTBRIGHT;
|
||||
|
||||
gl_drawinfo->drawlists[list].AddFlat (this);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -144,7 +144,7 @@ void GLPortal::DrawPortalStencil()
|
|||
|
||||
for (unsigned int i = 0; i<lines.Size(); i++)
|
||||
{
|
||||
lines[i].RenderWall(GLWall::RWF_NORENDER, NULL, &mPrimIndices[i * 2]);
|
||||
lines[i].RenderWall(GLWall::RWF_NORENDER, &mPrimIndices[i * 2]);
|
||||
}
|
||||
|
||||
if (cap)
|
||||
|
|
|
@ -351,120 +351,31 @@ void FGLRenderer::RenderScene(int recursion)
|
|||
|
||||
int pass;
|
||||
|
||||
if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && gl_dynlight_shader)
|
||||
if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights)
|
||||
{
|
||||
pass = GLPASS_ALL;
|
||||
}
|
||||
else if (gl_texture)
|
||||
else
|
||||
{
|
||||
pass = GLPASS_PLAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
pass = GLPASS_BASE;
|
||||
}
|
||||
|
||||
gl_RenderState.EnableTexture(gl_texture);
|
||||
gl_RenderState.EnableBrightmap(gl_fixedcolormap == CM_DEFAULT);
|
||||
gl_RenderState.EnableBrightmap(true);
|
||||
gl_drawinfo->drawlists[GLDL_PLAIN].Sort();
|
||||
gl_drawinfo->drawlists[GLDL_PLAIN].Draw(pass);
|
||||
gl_drawinfo->drawlists[GLDL_FOG].Sort();
|
||||
gl_drawinfo->drawlists[GLDL_FOG].Draw(pass);
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTFOG].Sort();
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTFOG].Draw(pass);
|
||||
|
||||
|
||||
// Part 2: masked geometry. This is set up so that only pixels with alpha>0.5 will show
|
||||
// Part 2: masked geometry. This is set up so that only pixels with alpha>gl_mask_threshold will show
|
||||
if (!gl_texture)
|
||||
{
|
||||
gl_RenderState.EnableTexture(true);
|
||||
gl_RenderState.SetTextureMode(TM_MASK);
|
||||
}
|
||||
if (pass == GLPASS_BASE) pass = GLPASS_BASE_MASKED;
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
||||
gl_drawinfo->drawlists[GLDL_MASKED].Sort();
|
||||
gl_drawinfo->drawlists[GLDL_MASKED].Draw(pass);
|
||||
gl_drawinfo->drawlists[GLDL_FOGMASKED].Sort();
|
||||
gl_drawinfo->drawlists[GLDL_FOGMASKED].Draw(pass);
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTFOGMASKED].Sort();
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTFOGMASKED].Draw(pass);
|
||||
|
||||
// And now the multipass stuff
|
||||
if (!gl_dynlight_shader && gl_lights)
|
||||
{
|
||||
// First pass: empty background with sector light only
|
||||
|
||||
// Part 1: solid geometry. This is set up so that there are no transparent parts
|
||||
|
||||
// remove any remaining texture bindings and shaders whick may get in the way.
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.EnableBrightmap(false);
|
||||
gl_RenderState.Apply();
|
||||
gl_drawinfo->drawlists[GLDL_LIGHT].Draw(GLPASS_BASE);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
|
||||
// Part 2: masked geometry. This is set up so that only pixels with alpha>0.5 will show
|
||||
// This creates a blank surface that only fills the nontransparent parts of the texture
|
||||
gl_RenderState.SetTextureMode(TM_MASK);
|
||||
gl_RenderState.EnableBrightmap(true);
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTBRIGHT].Draw(GLPASS_BASE_MASKED);
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTMASKED].Draw(GLPASS_BASE_MASKED);
|
||||
gl_RenderState.EnableBrightmap(false);
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
|
||||
|
||||
// second pass: draw lights (on fogged surfaces they are added to the textures!)
|
||||
glDepthMask(false);
|
||||
if (mLightCount && !gl_fixedcolormap)
|
||||
{
|
||||
if (gl_SetupLightTexture())
|
||||
{
|
||||
gl_RenderState.BlendFunc(GL_ONE, GL_ONE);
|
||||
glDepthFunc(GL_EQUAL);
|
||||
gl_RenderState.SetSoftLightLevel(255);
|
||||
for(int i=GLDL_FIRSTLIGHT; i<=GLDL_LASTLIGHT; i++)
|
||||
{
|
||||
gl_drawinfo->drawlists[i].Draw(GLPASS_LIGHT);
|
||||
}
|
||||
gl_RenderState.BlendEquation(GL_FUNC_ADD);
|
||||
}
|
||||
else gl_lights=false;
|
||||
}
|
||||
|
||||
// third pass: modulated texture
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO);
|
||||
gl_RenderState.EnableFog(false);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
if (gl_texture)
|
||||
{
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
gl_drawinfo->drawlists[GLDL_LIGHT].Sort();
|
||||
gl_drawinfo->drawlists[GLDL_LIGHT].Draw(GLPASS_TEXTURE);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTBRIGHT].Sort();
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTBRIGHT].Draw(GLPASS_TEXTURE);
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTMASKED].Sort();
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTMASKED].Draw(GLPASS_TEXTURE);
|
||||
}
|
||||
|
||||
// fourth pass: additive lights
|
||||
gl_RenderState.EnableFog(true);
|
||||
if (gl_lights && mLightCount && !gl_fixedcolormap)
|
||||
{
|
||||
gl_RenderState.BlendFunc(GL_ONE, GL_ONE);
|
||||
glDepthFunc(GL_EQUAL);
|
||||
if (gl_SetupLightTexture())
|
||||
{
|
||||
for(int i=0; i<GLDL_TRANSLUCENT; i++)
|
||||
{
|
||||
gl_drawinfo->drawlists[i].Draw(GLPASS_LIGHT_ADDITIVE);
|
||||
}
|
||||
gl_RenderState.BlendEquation(GL_FUNC_ADD);
|
||||
}
|
||||
else gl_lights=false;
|
||||
}
|
||||
}
|
||||
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
|
|
|
@ -511,6 +511,7 @@ void GLSkyPortal::DrawContents()
|
|||
gl_RenderState.Apply();
|
||||
glDrawArrays(GL_TRIANGLES, 0, 12);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
gl_RenderState.SetObjectColor(0xffffffff);
|
||||
}
|
||||
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ CVAR(Bool, gl_nolayer, false, 0)
|
|||
//==========================================================================
|
||||
void GLSprite::Draw(int pass)
|
||||
{
|
||||
if (pass!=GLPASS_PLAIN && pass != GLPASS_ALL && pass!=GLPASS_TRANSLUCENT) return;
|
||||
if (pass == GLPASS_DECALS) return;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -71,12 +71,10 @@ void gl_SetDynSpriteLight(AActor *self, fixed_t x, fixed_t y, fixed_t z, subsect
|
|||
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];
|
||||
FLightNode * node = subsec->lighthead;
|
||||
while (node)
|
||||
{
|
||||
light = node->lightsource;
|
||||
light=node->lightsource;
|
||||
if (!light->owned || light->target == NULL || light->target->IsVisibleToPlayer())
|
||||
{
|
||||
if (!(light->flags2&MF2_DORMANT) &&
|
||||
|
@ -112,7 +110,6 @@ void gl_SetDynSpriteLight(AActor *self, fixed_t x, fixed_t y, fixed_t z, subsect
|
|||
}
|
||||
node = node->nextLight;
|
||||
}
|
||||
}
|
||||
gl_RenderState.SetDynLight(out[0], out[1], out[2]);
|
||||
}
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ private:
|
|||
|
||||
void SetupLights();
|
||||
bool PrepareLight(texcoord * tcs, ADynamicLight * light);
|
||||
void RenderWall(int textured, ADynamicLight * light=NULL, unsigned int *store = NULL);
|
||||
void RenderWall(int textured, unsigned int *store = NULL);
|
||||
|
||||
void FloodPlane(int pass);
|
||||
|
||||
|
|
|
@ -114,9 +114,8 @@ void GLWall::PutWall(bool translucent)
|
|||
4, //RENDERWALL_SECTORSTACK, // special
|
||||
4, //RENDERWALL_PLANEMIRROR, // special
|
||||
4, //RENDERWALL_MIRROR, // special
|
||||
1, //RENDERWALL_MIRRORSURFACE, // needs special handling
|
||||
2, //RENDERWALL_M2SNF, // depends on render and texture settings, no fog
|
||||
2, //RENDERWALL_M2SFOG, // depends on render and texture settings, no fog
|
||||
1, //RENDERWALL_MIRRORSURFACE, // only created here from RENDERWALL_MIRROR
|
||||
2, //RENDERWALL_M2SNF, // depends on render and texture settings, no fog, used on mid texture lines with a fog boundary.
|
||||
3, //RENDERWALL_COLOR, // translucent
|
||||
2, //RENDERWALL_FFBLOCK // depends on render and texture settings
|
||||
4, //RENDERWALL_COLORLAYER // color layer needs special handling
|
||||
|
@ -145,47 +144,11 @@ void GLWall::PutWall(bool translucent)
|
|||
}
|
||||
else if (passflag[type]!=4) // non-translucent walls
|
||||
{
|
||||
static DrawListType list_indices[2][2][2]={
|
||||
{ { GLDL_PLAIN, GLDL_FOG }, { GLDL_MASKED, GLDL_FOGMASKED } },
|
||||
{ { GLDL_LIGHT, GLDL_LIGHTFOG }, { GLDL_LIGHTMASKED, GLDL_LIGHTFOGMASKED } }
|
||||
};
|
||||
|
||||
bool masked;
|
||||
bool light = false;
|
||||
|
||||
if (!gl_fixedcolormap)
|
||||
{
|
||||
if (gl_lights && !gl_dynlight_shader)
|
||||
{
|
||||
if (seg->sidedef == NULL)
|
||||
{
|
||||
light = false;
|
||||
}
|
||||
else if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
|
||||
{
|
||||
light = seg->sidedef->lighthead[0] != NULL;
|
||||
}
|
||||
else if (sub)
|
||||
{
|
||||
// for polyobjects we cannot use the side's light list.
|
||||
// We must use the subsector's.
|
||||
light = sub->lighthead[0] != NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
flags&=~GLWF_FOGGY;
|
||||
}
|
||||
|
||||
masked = passflag[type]==1? false : (light && type!=RENDERWALL_FFBLOCK) || (gltexture && gltexture->isMasked());
|
||||
|
||||
list = list_indices[light][masked][!!(flags&GLWF_FOGGY)];
|
||||
if (list == GLDL_LIGHT)
|
||||
{
|
||||
if (gltexture->tex->gl_info.Brightmap) list = GLDL_LIGHTBRIGHT;
|
||||
if (flags & GLWF_GLOW) list = GLDL_LIGHTBRIGHT;
|
||||
}
|
||||
masked = passflag[type]==1? false : (gltexture && gltexture->isMasked());
|
||||
list = masked ? GLDL_MASKED : GLDL_PLAIN;
|
||||
gl_drawinfo->drawlists[list].AddWall(this);
|
||||
|
||||
}
|
||||
|
@ -1514,11 +1477,12 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
|||
glseg.x2= FIXED2FLOAT(v2->x);
|
||||
glseg.y2= FIXED2FLOAT(v2->y);
|
||||
Colormap=frontsector->ColorMap;
|
||||
flags = (!gl_isBlack(Colormap.FadeColor) || level.flags&LEVEL_HASFADETABLE)? GLWF_FOGGY : 0;
|
||||
flags = 0;
|
||||
|
||||
int rel = 0;
|
||||
int orglightlevel = gl_ClampLight(frontsector->lightlevel);
|
||||
lightlevel = gl_ClampLight(seg->sidedef->GetLightLevel(!!(flags&GLWF_FOGGY), orglightlevel, false, &rel));
|
||||
bool foggy = (!gl_isBlack(Colormap.FadeColor) || level.flags&LEVEL_HASFADETABLE); // fog disables fake contrast
|
||||
lightlevel = gl_ClampLight(seg->sidedef->GetLightLevel(foggy, orglightlevel, false, &rel));
|
||||
if (orglightlevel >= 253) // with the software renderer fake contrast won't be visible above this.
|
||||
{
|
||||
rellight = 0;
|
||||
|
@ -1764,7 +1728,7 @@ void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t *
|
|||
glseg.fracleft = 0;
|
||||
glseg.fracright = 1;
|
||||
|
||||
flags = (!gl_isBlack(Colormap.FadeColor) || level.flags&LEVEL_HASFADETABLE)? GLWF_FOGGY : 0;
|
||||
flags = 0;
|
||||
|
||||
// can't do fake contrast without a sidedef
|
||||
lightlevel = gl_ClampLight(frontsector->lightlevel);
|
||||
|
|
|
@ -62,57 +62,6 @@
|
|||
|
||||
EXTERN_CVAR(Bool, gl_seamless)
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets up the texture coordinates for one light to be rendered
|
||||
//
|
||||
//==========================================================================
|
||||
bool GLWall::PrepareLight(texcoord * tcs, ADynamicLight * light)
|
||||
{
|
||||
float vtx[]={glseg.x1,zbottom[0],glseg.y1, glseg.x1,ztop[0],glseg.y1, glseg.x2,ztop[1],glseg.y2, glseg.x2,zbottom[1],glseg.y2};
|
||||
Plane p;
|
||||
Vector nearPt, up, right;
|
||||
float scale;
|
||||
|
||||
p.Init(vtx,4);
|
||||
|
||||
if (!p.ValidNormal())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!gl_SetupLight(p, light, nearPt, up, right, scale, Colormap.desaturation, true, !!(flags&GLWF_FOGGY)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tcs != NULL)
|
||||
{
|
||||
Vector t1;
|
||||
int outcnt[4]={0,0,0,0};
|
||||
|
||||
for(int i=0;i<4;i++)
|
||||
{
|
||||
t1.Set(&vtx[i*3]);
|
||||
Vector nearToVert = t1 - nearPt;
|
||||
tcs[i].u = (nearToVert.Dot(right) * scale) + 0.5f;
|
||||
tcs[i].v = (nearToVert.Dot(up) * scale) + 0.5f;
|
||||
|
||||
// quick check whether the light touches this polygon
|
||||
if (tcs[i].u<0) outcnt[0]++;
|
||||
if (tcs[i].u>1) outcnt[1]++;
|
||||
if (tcs[i].v<0) outcnt[2]++;
|
||||
if (tcs[i].v>1) outcnt[3]++;
|
||||
|
||||
}
|
||||
// The light doesn't touch this polygon
|
||||
if (outcnt[0]==4 || outcnt[1]==4 || outcnt[2]==4 || outcnt[3]==4) return false;
|
||||
}
|
||||
|
||||
draw_dlight++;
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Collect lights for shader
|
||||
|
@ -132,8 +81,6 @@ void GLWall::SetupLights()
|
|||
{
|
||||
return;
|
||||
}
|
||||
for(int i=0;i<2;i++)
|
||||
{
|
||||
FLightNode *node;
|
||||
if (seg->sidedef == NULL)
|
||||
{
|
||||
|
@ -141,12 +88,12 @@ void GLWall::SetupLights()
|
|||
}
|
||||
else if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
|
||||
{
|
||||
node = seg->sidedef->lighthead[i];
|
||||
node = seg->sidedef->lighthead;
|
||||
}
|
||||
else if (sub)
|
||||
{
|
||||
// Polobject segs cannot be checked per sidedef so use the subsector instead.
|
||||
node = sub->lighthead[i];
|
||||
node = sub->lighthead;
|
||||
}
|
||||
else node = NULL;
|
||||
|
||||
|
@ -203,7 +150,6 @@ void GLWall::SetupLights()
|
|||
}
|
||||
node = node->nextLight;
|
||||
}
|
||||
}
|
||||
int numlights[3];
|
||||
|
||||
lightdata.Combine(numlights, gl.MaxLights());
|
||||
|
@ -223,13 +169,11 @@ void GLWall::SetupLights()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLWall::RenderWall(int textured, ADynamicLight * light, unsigned int *store)
|
||||
void GLWall::RenderWall(int textured, unsigned int *store)
|
||||
{
|
||||
static texcoord tcs[4]; // making this variable static saves us a relatively costly stack integrity check.
|
||||
bool split = (gl_seamless && !(textured&RWF_NOSPLIT) && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ));
|
||||
|
||||
if (!light)
|
||||
{
|
||||
tcs[0]=lolft;
|
||||
tcs[1]=uplft;
|
||||
tcs[2]=uprgt;
|
||||
|
@ -240,13 +184,6 @@ void GLWall::RenderWall(int textured, ADynamicLight * light, unsigned int *store
|
|||
gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!PrepareLight(tcs, light)) return;
|
||||
}
|
||||
|
||||
|
||||
if (!(textured & RWF_NORENDER))
|
||||
{
|
||||
// disable the clip plane if it isn't needed (which can be determined by a simple check.)
|
||||
|
@ -422,7 +359,6 @@ void GLWall::RenderTranslucentWall()
|
|||
//==========================================================================
|
||||
void GLWall::Draw(int pass)
|
||||
{
|
||||
FLightNode * node;
|
||||
int rel;
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
@ -461,64 +397,6 @@ void GLWall::Draw(int pass)
|
|||
gl_RenderState.EnableLight(false);
|
||||
break;
|
||||
|
||||
case GLPASS_BASE: // Base pass for non-masked polygons (all opaque geometry)
|
||||
case GLPASS_BASE_MASKED: // Base pass for masked polygons (2sided mid-textures and transparent 3D floors)
|
||||
rel = rellight + getExtraLight();
|
||||
gl_SetColor(lightlevel, rel, Colormap,1.0f);
|
||||
if (!(flags&GLWF_FOGGY))
|
||||
{
|
||||
if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||
else gl_SetFog(255, 0, NULL, false);
|
||||
}
|
||||
gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW));
|
||||
// fall through
|
||||
|
||||
if (pass != GLPASS_BASE)
|
||||
{
|
||||
gltexture->Bind(flags, 0);
|
||||
}
|
||||
RenderWall(RWF_TEXTURED|RWF_GLOW);
|
||||
gl_RenderState.EnableGlow(false);
|
||||
gl_RenderState.EnableLight(false);
|
||||
break;
|
||||
|
||||
case GLPASS_TEXTURE: // modulated texture
|
||||
gltexture->Bind(flags, 0);
|
||||
RenderWall(RWF_TEXTURED);
|
||||
break;
|
||||
|
||||
case GLPASS_LIGHT:
|
||||
case GLPASS_LIGHT_ADDITIVE:
|
||||
// black fog is diminishing light and should affect lights less than the rest!
|
||||
if (!(flags&GLWF_FOGGY)) gl_SetFog((255+lightlevel)>>1, 0, NULL, false);
|
||||
else gl_SetFog(lightlevel, 0, &Colormap, true);
|
||||
|
||||
if (seg->sidedef == NULL)
|
||||
{
|
||||
node = NULL;
|
||||
}
|
||||
else if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
|
||||
{
|
||||
// Iterate through all dynamic lights which touch this wall and render them
|
||||
node = seg->sidedef->lighthead[pass==GLPASS_LIGHT_ADDITIVE];
|
||||
}
|
||||
else if (sub)
|
||||
{
|
||||
// To avoid constant rechecking for polyobjects use the subsector's lightlist instead
|
||||
node = sub->lighthead[pass==GLPASS_LIGHT_ADDITIVE];
|
||||
}
|
||||
else node = NULL;
|
||||
while (node)
|
||||
{
|
||||
if (!(node->lightsource->flags2&MF2_DORMANT))
|
||||
{
|
||||
iter_dlight++;
|
||||
RenderWall(RWF_TEXTURED, node->lightsource);
|
||||
}
|
||||
node = node->nextLight;
|
||||
}
|
||||
break;
|
||||
|
||||
case GLPASS_DECALS:
|
||||
case GLPASS_DECALS_NOFOG:
|
||||
if (seg->sidedef && seg->sidedef->AttachedDecals)
|
||||
|
|
|
@ -772,7 +772,7 @@ struct sector_t
|
|||
int subsectorcount; // list of subsectors
|
||||
subsector_t ** subsectors;
|
||||
FPortal * portals[2]; // floor and ceiling portals
|
||||
FLightNode * lighthead[2];
|
||||
FLightNode * lighthead;
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -949,7 +949,7 @@ struct side_t
|
|||
vertex_t *V2() const;
|
||||
|
||||
//For GL
|
||||
FLightNode * lighthead[2]; // all blended lights that may affect this wall
|
||||
FLightNode * lighthead; // all blended lights that may affect this wall
|
||||
|
||||
seg_t **segs; // all segs belonging to this sidedef in ascending order. Used for precise rendering
|
||||
int numsegs;
|
||||
|
@ -1082,7 +1082,7 @@ struct subsector_t
|
|||
|
||||
void BuildPolyBSP();
|
||||
// subsector related GL data
|
||||
FLightNode * lighthead[2]; // Light nodes (blended and additive)
|
||||
FLightNode * lighthead; // Light nodes (blended and additive)
|
||||
int validcount;
|
||||
short mapsection;
|
||||
char hacked; // 1: is part of a render hack
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 13 KiB |
Loading…
Reference in a new issue