2016-09-14 18:01:13 +00:00
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Copyright(C) 2003-2016 Christoph Oelckers
|
|
|
|
// All rights reserved.
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Lesser General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
|
|
// along with this program. If not, see http://www.gnu.org/licenses/
|
|
|
|
//
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
//
|
2013-06-23 07:49:34 +00:00
|
|
|
/*
|
|
|
|
** gl_decal.cpp
|
|
|
|
** OpenGL decal rendering code
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "doomdata.h"
|
|
|
|
#include "gl/system/gl_system.h"
|
|
|
|
#include "a_sharedglobal.h"
|
|
|
|
#include "r_utility.h"
|
2017-03-15 23:56:03 +00:00
|
|
|
#include "g_levellocals.h"
|
2013-06-23 07:49:34 +00:00
|
|
|
|
2018-04-25 18:33:55 +00:00
|
|
|
#include "hwrenderer/utility/hw_cvars.h"
|
2014-05-12 20:46:30 +00:00
|
|
|
#include "gl/data/gl_vertexbuffer.h"
|
2013-06-23 07:49:34 +00:00
|
|
|
#include "gl/renderer/gl_renderer.h"
|
|
|
|
#include "gl/renderer/gl_lightdata.h"
|
|
|
|
#include "gl/renderer/gl_renderstate.h"
|
|
|
|
#include "gl/scene/gl_drawinfo.h"
|
2017-03-12 20:57:39 +00:00
|
|
|
#include "gl/scene/gl_scenedrawer.h"
|
2016-08-22 12:00:25 +00:00
|
|
|
#include "gl/renderer/gl_quaddrawer.h"
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
struct DecalVertex
|
|
|
|
{
|
|
|
|
float x,y,z;
|
|
|
|
float u,v;
|
|
|
|
};
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//==========================================================================
|
2018-04-25 20:09:12 +00:00
|
|
|
void FDrawInfo::DrawDecal(GLWall *wall, DBaseDecal *decal)
|
2013-06-23 07:49:34 +00:00
|
|
|
{
|
2018-04-25 20:09:12 +00:00
|
|
|
auto seg = wall->seg;
|
|
|
|
line_t * line = seg->linedef;
|
|
|
|
side_t * side = seg->sidedef;
|
2013-06-23 07:49:34 +00:00
|
|
|
int i;
|
2016-03-22 22:19:21 +00:00
|
|
|
float zpos;
|
2013-06-23 07:49:34 +00:00
|
|
|
int light;
|
|
|
|
int rel;
|
|
|
|
float a;
|
2014-05-11 17:44:19 +00:00
|
|
|
bool flipx, flipy;
|
2013-06-23 07:49:34 +00:00
|
|
|
DecalVertex dv[4];
|
|
|
|
FTextureID decalTile;
|
2018-04-25 20:09:12 +00:00
|
|
|
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
if (decal->RenderFlags & RF_INVISIBLE) return;
|
2018-04-25 20:09:12 +00:00
|
|
|
if (wall->type == RENDERWALL_FFBLOCK && wall->gltexture->isMasked()) return; // No decals on 3D floors with transparent textures.
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
//if (decal->sprite != 0xffff)
|
|
|
|
{
|
|
|
|
decalTile = decal->PicNum;
|
|
|
|
flipx = !!(decal->RenderFlags & RF_XFLIP);
|
|
|
|
flipy = !!(decal->RenderFlags & RF_YFLIP);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
else
|
|
|
|
{
|
|
|
|
decalTile = SpriteFrames[sprites[decal->sprite].spriteframes + decal->frame].lump[0];
|
|
|
|
flipx = SpriteFrames[sprites[decal->sprite].spriteframes + decal->frame].flip & 1;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
FTexture *texture = TexMan[decalTile];
|
|
|
|
if (texture == NULL) return;
|
|
|
|
|
|
|
|
FMaterial *tex;
|
|
|
|
|
|
|
|
|
2014-08-22 21:50:38 +00:00
|
|
|
tex = FMaterial::ValidateTexture(texture, true);
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
// the sectors are only used for their texture origin coordinates
|
|
|
|
// so we don't need the fake sectors for deep water etc.
|
|
|
|
// As this is a completely split wall fragment no further splits are
|
|
|
|
// necessary for the decal.
|
|
|
|
sector_t *frontsector;
|
|
|
|
|
|
|
|
// for 3d-floor segments use the model sector as reference
|
2018-04-25 20:09:12 +00:00
|
|
|
if ((decal->RenderFlags&RF_CLIPMASK) == RF_CLIPMID) frontsector = decal->Sector;
|
|
|
|
else frontsector = seg->frontsector;
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
switch (decal->RenderFlags & RF_RELMASK)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
// No valid decal can have this type. If one is encountered anyway
|
|
|
|
// it is in some way invalid so skip it.
|
|
|
|
return;
|
|
|
|
//zpos = decal->z;
|
|
|
|
//break;
|
|
|
|
|
|
|
|
case RF_RELUPPER:
|
2018-04-25 20:09:12 +00:00
|
|
|
if (wall->type != RENDERWALL_TOP) return;
|
2013-06-23 07:49:34 +00:00
|
|
|
if (line->flags & ML_DONTPEGTOP)
|
|
|
|
{
|
2016-04-24 11:35:43 +00:00
|
|
|
zpos = decal->Z + frontsector->GetPlaneTexZ(sector_t::ceiling);
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-04-24 11:35:43 +00:00
|
|
|
zpos = decal->Z + seg->backsector->GetPlaneTexZ(sector_t::ceiling);
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RF_RELLOWER:
|
2018-04-25 20:09:12 +00:00
|
|
|
if (wall->type != RENDERWALL_BOTTOM) return;
|
2013-06-23 07:49:34 +00:00
|
|
|
if (line->flags & ML_DONTPEGBOTTOM)
|
|
|
|
{
|
2016-04-24 11:35:43 +00:00
|
|
|
zpos = decal->Z + frontsector->GetPlaneTexZ(sector_t::ceiling);
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-04-24 11:35:43 +00:00
|
|
|
zpos = decal->Z + seg->backsector->GetPlaneTexZ(sector_t::floor);
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RF_RELMID:
|
2018-04-25 20:09:12 +00:00
|
|
|
if (wall->type == RENDERWALL_TOP || wall->type == RENDERWALL_BOTTOM) return;
|
2013-06-23 07:49:34 +00:00
|
|
|
if (line->flags & ML_DONTPEGBOTTOM)
|
|
|
|
{
|
2016-04-24 11:35:43 +00:00
|
|
|
zpos = decal->Z + frontsector->GetPlaneTexZ(sector_t::floor);
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-04-24 11:35:43 +00:00
|
|
|
zpos = decal->Z + frontsector->GetPlaneTexZ(sector_t::ceiling);
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
}
|
2018-04-25 20:09:12 +00:00
|
|
|
|
2013-06-23 07:49:34 +00:00
|
|
|
if (decal->RenderFlags & RF_FULLBRIGHT)
|
|
|
|
{
|
|
|
|
light = 255;
|
|
|
|
rel = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-04-25 20:09:12 +00:00
|
|
|
light = wall->lightlevel;
|
|
|
|
rel = wall->rellight + getExtraLight();
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
2018-04-25 20:09:12 +00:00
|
|
|
|
|
|
|
FColormap p = wall->Colormap;
|
|
|
|
|
2017-03-15 23:56:03 +00:00
|
|
|
if (level.flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING)
|
2013-06-23 07:49:34 +00:00
|
|
|
{
|
2014-05-11 20:57:42 +00:00
|
|
|
p.Decolorize();
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
2018-04-25 20:09:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2016-03-22 22:19:21 +00:00
|
|
|
a = decal->Alpha;
|
2018-04-25 20:09:12 +00:00
|
|
|
|
2013-06-23 07:49:34 +00:00
|
|
|
// now clip the decal to the actual polygon
|
2016-03-22 22:19:21 +00:00
|
|
|
float decalwidth = tex->TextureWidth() * decal->ScaleX;
|
2018-04-25 20:09:12 +00:00
|
|
|
float decalheight = tex->TextureHeight() * decal->ScaleY;
|
2016-03-22 22:19:21 +00:00
|
|
|
float decallefto = tex->GetLeftOffset() * decal->ScaleX;
|
2018-04-25 20:09:12 +00:00
|
|
|
float decaltopo = tex->GetTopOffset() * decal->ScaleY;
|
2013-06-23 07:49:34 +00:00
|
|
|
|
2018-04-25 20:09:12 +00:00
|
|
|
auto &glseg = wall->glseg;
|
2013-06-23 07:49:34 +00:00
|
|
|
float leftedge = glseg.fracleft * side->TexelLength;
|
|
|
|
float linelength = glseg.fracright * side->TexelLength - leftedge;
|
|
|
|
|
|
|
|
// texel index of the decal's left edge
|
2018-04-25 20:09:12 +00:00
|
|
|
float decalpixpos = (float)side->TexelLength * decal->LeftDistance - (flipx ? decalwidth - decallefto : decallefto) - leftedge;
|
2013-06-23 07:49:34 +00:00
|
|
|
|
2018-04-25 20:09:12 +00:00
|
|
|
float left, right;
|
|
|
|
float lefttex, righttex;
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
// decal is off the left edge
|
|
|
|
if (decalpixpos < 0)
|
|
|
|
{
|
|
|
|
left = 0;
|
|
|
|
lefttex = -decalpixpos;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
left = decalpixpos;
|
|
|
|
lefttex = 0;
|
|
|
|
}
|
2018-04-25 20:09:12 +00:00
|
|
|
|
2013-06-23 07:49:34 +00:00
|
|
|
// decal is off the right edge
|
|
|
|
if (decalpixpos + decalwidth > linelength)
|
|
|
|
{
|
|
|
|
right = linelength;
|
|
|
|
righttex = right - decalpixpos;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
right = decalpixpos + decalwidth;
|
|
|
|
righttex = decalwidth;
|
|
|
|
}
|
2018-04-25 20:09:12 +00:00
|
|
|
if (right <= left) return; // nothing to draw
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
// one texture unit on the wall as vector
|
2018-04-25 20:09:12 +00:00
|
|
|
float vx = (glseg.x2 - glseg.x1) / linelength;
|
|
|
|
float vy = (glseg.y2 - glseg.y1) / linelength;
|
2013-06-23 07:49:34 +00:00
|
|
|
|
2018-04-25 20:09:12 +00:00
|
|
|
dv[1].x = dv[0].x = glseg.x1 + vx * left;
|
|
|
|
dv[1].y = dv[0].y = glseg.y1 + vy * left;
|
2013-06-23 07:49:34 +00:00
|
|
|
|
2018-04-25 20:09:12 +00:00
|
|
|
dv[3].x = dv[2].x = glseg.x1 + vx * right;
|
|
|
|
dv[3].y = dv[2].y = glseg.y1 + vy * right;
|
2013-06-23 07:49:34 +00:00
|
|
|
|
2018-04-25 20:09:12 +00:00
|
|
|
zpos += (flipy ? decalheight - decaltopo : decaltopo);
|
2013-06-23 07:49:34 +00:00
|
|
|
|
2018-04-25 20:09:12 +00:00
|
|
|
dv[1].z = dv[2].z = zpos;
|
|
|
|
dv[0].z = dv[3].z = dv[1].z - decalheight;
|
|
|
|
dv[1].v = dv[2].v = tex->GetVT();
|
|
|
|
|
|
|
|
dv[1].u = dv[0].u = tex->GetU(lefttex / decal->ScaleX);
|
|
|
|
dv[3].u = dv[2].u = tex->GetU(righttex / decal->ScaleX);
|
|
|
|
dv[0].v = dv[3].v = tex->GetVB();
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
// now clip to the top plane
|
2018-04-25 20:09:12 +00:00
|
|
|
float vzt = (wall->ztop[1] - wall->ztop[0]) / linelength;
|
|
|
|
float topleft = wall->ztop[0] + vzt * left;
|
|
|
|
float topright = wall->ztop[0] + vzt * right;
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
// completely below the wall
|
2018-04-25 20:09:12 +00:00
|
|
|
if (topleft < dv[0].z && topright < dv[3].z)
|
2013-06-23 07:49:34 +00:00
|
|
|
return;
|
|
|
|
|
2018-04-25 20:09:12 +00:00
|
|
|
if (topleft < dv[1].z || topright < dv[2].z)
|
2013-06-23 07:49:34 +00:00
|
|
|
{
|
|
|
|
// decal has to be clipped at the top
|
|
|
|
// let texture clamping handle all extreme cases
|
2018-04-25 20:09:12 +00:00
|
|
|
dv[1].v = (dv[1].z - topleft) / (dv[1].z - dv[0].z)*dv[0].v;
|
|
|
|
dv[2].v = (dv[2].z - topright) / (dv[2].z - dv[3].z)*dv[3].v;
|
|
|
|
dv[1].z = topleft;
|
|
|
|
dv[2].z = topright;
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// now clip to the bottom plane
|
2018-04-25 20:09:12 +00:00
|
|
|
float vzb = (wall->zbottom[1] - wall->zbottom[0]) / linelength;
|
|
|
|
float bottomleft = wall->zbottom[0] + vzb * left;
|
|
|
|
float bottomright = wall->zbottom[0] + vzb * right;
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
// completely above the wall
|
2018-04-25 20:09:12 +00:00
|
|
|
if (bottomleft > dv[1].z && bottomright > dv[2].z)
|
2013-06-23 07:49:34 +00:00
|
|
|
return;
|
|
|
|
|
2018-04-25 20:09:12 +00:00
|
|
|
if (bottomleft > dv[0].z || bottomright > dv[3].z)
|
2013-06-23 07:49:34 +00:00
|
|
|
{
|
|
|
|
// decal has to be clipped at the bottom
|
|
|
|
// let texture clamping handle all extreme cases
|
2018-04-25 20:09:12 +00:00
|
|
|
dv[0].v = (dv[1].z - bottomleft) / (dv[1].z - dv[0].z)*(dv[0].v - dv[1].v) + dv[1].v;
|
|
|
|
dv[3].v = (dv[2].z - bottomright) / (dv[2].z - dv[3].z)*(dv[3].v - dv[2].v) + dv[2].v;
|
|
|
|
dv[0].z = bottomleft;
|
|
|
|
dv[3].z = bottomright;
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (flipx)
|
|
|
|
{
|
|
|
|
float ur = tex->GetUR();
|
2018-04-25 20:09:12 +00:00
|
|
|
for (i = 0; i < 4; i++) dv[i].u = ur - dv[i].u;
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
if (flipy)
|
|
|
|
{
|
|
|
|
float vb = tex->GetVB();
|
2018-04-25 20:09:12 +00:00
|
|
|
for (i = 0; i < 4; i++) dv[i].v = vb - dv[i].v;
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
|
2014-05-11 17:44:19 +00:00
|
|
|
// calculate dynamic light effect.
|
2017-03-12 20:57:39 +00:00
|
|
|
if (gl_lights && GLRenderer->mLightCount && !mDrawer->FixedColormap && gl_light_sprites)
|
2013-06-23 07:49:34 +00:00
|
|
|
{
|
2014-05-11 17:44:19 +00:00
|
|
|
// Note: This should be replaced with proper shader based lighting.
|
2016-03-22 22:19:21 +00:00
|
|
|
double x, y;
|
2014-05-11 17:44:19 +00:00
|
|
|
decal->GetXY(seg->sidedef, x, y);
|
2018-04-25 20:09:12 +00:00
|
|
|
gl_SetDynSpriteLight(nullptr, x, y, zpos - decalheight * 0.5f, wall->sub);
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
2014-05-11 17:44:19 +00:00
|
|
|
|
|
|
|
// alpha color only has an effect when using an alpha texture.
|
|
|
|
if (decal->RenderStyle.Flags & STYLEF_RedIsAlpha)
|
2013-06-23 07:49:34 +00:00
|
|
|
{
|
2018-04-25 20:09:12 +00:00
|
|
|
gl_RenderState.SetObjectColor(decal->AlphaColor | 0xff000000);
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
|
2014-05-11 17:44:19 +00:00
|
|
|
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
gl_SetRenderStyle(decal->RenderStyle, false, false);
|
2014-09-09 10:00:42 +00:00
|
|
|
gl_RenderState.SetMaterial(tex, CLAMP_XY, decal->Translation, 0, !!(decal->RenderStyle.Flags & STYLEF_RedIsAlpha));
|
2014-05-11 17:44:19 +00:00
|
|
|
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
// If srcalpha is one it looks better with a higher alpha threshold
|
2014-07-14 19:14:43 +00:00
|
|
|
if (decal->RenderStyle.SrcAlpha == STYLEALPHA_One) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold);
|
2013-06-23 07:49:34 +00:00
|
|
|
else gl_RenderState.AlphaFunc(GL_GREATER, 0.f);
|
|
|
|
|
2016-02-01 20:45:26 +00:00
|
|
|
|
2017-03-12 20:57:39 +00:00
|
|
|
mDrawer->SetColor(light, rel, p, a);
|
2016-02-01 20:45:26 +00:00
|
|
|
// for additively drawn decals we must temporarily set the fog color to black.
|
|
|
|
PalEntry fc = gl_RenderState.GetFogColor();
|
|
|
|
if (decal->RenderStyle.BlendOp == STYLEOP_Add && decal->RenderStyle.DestAlpha == STYLEALPHA_One)
|
2013-06-23 07:49:34 +00:00
|
|
|
{
|
2018-04-25 20:09:12 +00:00
|
|
|
gl_RenderState.SetFog(0, -1);
|
2016-02-01 20:45:26 +00:00
|
|
|
}
|
2016-02-01 20:50:55 +00:00
|
|
|
|
2016-10-13 16:04:00 +00:00
|
|
|
gl_RenderState.SetNormal(glseg.Normal());
|
|
|
|
|
2016-08-22 12:00:25 +00:00
|
|
|
FQuadDrawer qd;
|
2016-02-01 20:50:55 +00:00
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
{
|
2016-08-22 12:00:25 +00:00
|
|
|
qd.Set(i, dv[i].x, dv[i].z, dv[i].y, dv[i].u, dv[i].v);
|
2016-02-01 20:50:55 +00:00
|
|
|
}
|
|
|
|
|
2018-04-25 20:09:12 +00:00
|
|
|
if (wall->lightlist == nullptr)
|
2016-02-01 20:45:26 +00:00
|
|
|
{
|
|
|
|
gl_RenderState.Apply();
|
2016-08-22 12:00:25 +00:00
|
|
|
qd.Render(GL_TRIANGLE_FAN);
|
2016-02-01 20:45:26 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-04-25 20:09:12 +00:00
|
|
|
auto &lightlist = *wall->lightlist;
|
|
|
|
|
|
|
|
for (unsigned k = 0; k < lightlist.Size(); k++)
|
2016-02-01 20:45:26 +00:00
|
|
|
{
|
2018-04-25 20:09:12 +00:00
|
|
|
secplane_t &lowplane = k == lightlist.Size() - 1 ? wall->bottomplane : lightlist[k + 1].plane;
|
2016-02-01 20:45:26 +00:00
|
|
|
|
2016-02-03 12:03:38 +00:00
|
|
|
float low1 = lowplane.ZatPoint(dv[1].x, dv[1].y);
|
2016-02-01 20:45:26 +00:00
|
|
|
float low2 = lowplane.ZatPoint(dv[2].x, dv[2].y);
|
|
|
|
|
2016-02-04 00:12:18 +00:00
|
|
|
if (low1 < dv[1].z || low2 < dv[2].z)
|
2016-02-01 20:45:26 +00:00
|
|
|
{
|
2018-04-26 22:22:00 +00:00
|
|
|
int thisll = lightlist[k].caster != NULL ? hw_ClampLight(*lightlist[k].p_lightlevel) : wall->lightlevel;
|
2016-02-01 20:45:26 +00:00
|
|
|
FColormap thiscm;
|
2018-04-25 20:09:12 +00:00
|
|
|
thiscm.FadeColor = wall->Colormap.FadeColor;
|
|
|
|
thiscm.CopyFrom3DLight(&lightlist[k]);
|
2017-03-12 20:57:39 +00:00
|
|
|
mDrawer->SetColor(thisll, rel, thiscm, a);
|
2017-03-15 23:56:03 +00:00
|
|
|
if (level.flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING) thiscm.Decolorize();
|
2018-04-25 20:09:12 +00:00
|
|
|
mDrawer->SetFog(thisll, rel, &thiscm, wall->RenderStyle == STYLE_Add);
|
|
|
|
gl_RenderState.SetSplitPlanes(lightlist[k].plane, lowplane);
|
2016-02-01 20:45:26 +00:00
|
|
|
|
|
|
|
gl_RenderState.Apply();
|
2016-08-22 12:00:25 +00:00
|
|
|
qd.Render(GL_TRIANGLE_FAN);
|
2016-02-01 20:45:26 +00:00
|
|
|
}
|
|
|
|
if (low1 <= dv[0].z && low2 <= dv[3].z) break;
|
|
|
|
}
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
2014-06-14 23:14:41 +00:00
|
|
|
|
2013-06-23 07:49:34 +00:00
|
|
|
rendered_decals++;
|
2014-05-11 17:44:19 +00:00
|
|
|
gl_RenderState.SetTextureMode(TM_MODULATE);
|
|
|
|
gl_RenderState.SetObjectColor(0xffffffff);
|
2018-04-25 20:09:12 +00:00
|
|
|
gl_RenderState.SetFog(fc, -1);
|
|
|
|
gl_RenderState.SetDynLight(0, 0, 0);
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//==========================================================================
|
2018-04-25 20:09:12 +00:00
|
|
|
void FDrawInfo::DoDrawDecals(GLWall *wall)
|
2013-06-23 07:49:34 +00:00
|
|
|
{
|
2018-04-25 20:09:12 +00:00
|
|
|
if (wall->seg->sidedef && wall->seg->sidedef->AttachedDecals)
|
2013-06-23 07:49:34 +00:00
|
|
|
{
|
2018-04-25 20:09:12 +00:00
|
|
|
if (wall->lightlist != nullptr)
|
2016-02-01 20:45:26 +00:00
|
|
|
{
|
|
|
|
gl_RenderState.EnableSplit(true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-04-25 20:09:12 +00:00
|
|
|
mDrawer->SetFog(wall->lightlevel, wall->rellight + getExtraLight(), &wall->Colormap, false);
|
2016-02-01 20:45:26 +00:00
|
|
|
}
|
|
|
|
|
2018-04-25 20:09:12 +00:00
|
|
|
DBaseDecal *decal = wall->seg->sidedef->AttachedDecals;
|
2014-08-30 13:34:14 +00:00
|
|
|
while (decal)
|
|
|
|
{
|
2018-04-25 20:09:12 +00:00
|
|
|
DrawDecal(wall, decal);
|
2014-08-30 13:34:14 +00:00
|
|
|
decal = decal->WallNext;
|
|
|
|
}
|
2016-02-01 20:45:26 +00:00
|
|
|
|
2018-04-25 20:09:12 +00:00
|
|
|
if (wall->lightlist != nullptr)
|
2016-02-01 20:45:26 +00:00
|
|
|
{
|
|
|
|
gl_RenderState.EnableSplit(false);
|
|
|
|
}
|
|
|
|
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|