mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 15:21:51 +00:00
- moved sprite drawer to hwrenderer as well.
This commit is contained in:
parent
346a9ce149
commit
3775c4756e
11 changed files with 281 additions and 340 deletions
|
@ -821,7 +821,6 @@ set( FASTMATH_SOURCES
|
|||
textures/hires/xbr/xbrz.cpp
|
||||
textures/hires/xbr/xbrz_old.cpp
|
||||
gl/scene/gl_drawinfo.cpp
|
||||
gl/scene/gl_sprite.cpp
|
||||
gl/scene/gl_skydome.cpp
|
||||
gl/scene/gl_weapon.cpp
|
||||
gl/scene/gl_scene.cpp
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "gl/scene/gl_portal.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
#include "gl/models/gl_models.h"
|
||||
|
||||
class FDrawInfoList
|
||||
{
|
||||
|
@ -90,13 +91,13 @@ void FDrawInfo::DoDrawSorted(HWDrawList *dl, SortNode * head)
|
|||
DoDrawSorted(dl, head->left);
|
||||
gl_RenderState.SetClipSplit(clipsplit);
|
||||
}
|
||||
dl->DoDraw(this, gl_RenderState, true, GLPASS_TRANSLUCENT, head->itemindex, true);
|
||||
dl->DoDraw(this, gl_RenderState, true, head->itemindex);
|
||||
if (head->equal)
|
||||
{
|
||||
SortNode * ehead=head->equal;
|
||||
while (ehead)
|
||||
{
|
||||
dl->DoDraw(this, gl_RenderState, true, GLPASS_TRANSLUCENT, ehead->itemindex, true);
|
||||
dl->DoDraw(this, gl_RenderState, true, ehead->itemindex);
|
||||
ehead=ehead->equal;
|
||||
}
|
||||
}
|
||||
|
@ -298,6 +299,12 @@ void FDrawInfo::DrawIndexed(EDrawType dt, FRenderState &state, int index, int co
|
|||
drawcalls.Unclock();
|
||||
}
|
||||
|
||||
void FDrawInfo::DrawModel(GLSprite *spr, FRenderState &state)
|
||||
{
|
||||
FGLModelRenderer renderer(this, spr->dynlightindex);
|
||||
renderer.RenderModel(spr->x, spr->y, spr->z, spr->modelframe, spr->actor, Viewpoint.TicFrac);
|
||||
}
|
||||
|
||||
void FDrawInfo::SetDepthMask(bool on)
|
||||
{
|
||||
glDepthMask(on);
|
||||
|
@ -357,3 +364,26 @@ void FDrawInfo::AddFlat(GLFlat *flat, bool fog)
|
|||
*newflat = *flat;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void FDrawInfo::AddSprite(GLSprite *sprite, bool translucent)
|
||||
{
|
||||
int list;
|
||||
// [BB] Allow models to be drawn in the GLDL_TRANSLUCENT pass.
|
||||
if (translucent || sprite->actor == nullptr || (!sprite->modelframe && (sprite->actor->renderflags & RF_SPRITETYPEMASK) != RF_WALLSPRITE))
|
||||
{
|
||||
list = GLDL_TRANSLUCENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
list = GLDL_MODELS;
|
||||
}
|
||||
|
||||
auto newsprt = drawlists[list].NewSprite();
|
||||
*newsprt = *sprite;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,11 +26,6 @@ enum DrawListType
|
|||
GLDL_TYPES,
|
||||
};
|
||||
|
||||
enum Drawpasses
|
||||
{
|
||||
GLPASS_ALL, // Main pass with dynamic lights
|
||||
GLPASS_TRANSLUCENT, // Draws translucent objects
|
||||
};
|
||||
|
||||
struct FDrawInfo : public HWDrawInfo
|
||||
{
|
||||
|
@ -52,14 +47,14 @@ struct FDrawInfo : public HWDrawInfo
|
|||
|
||||
void Draw(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) override;
|
||||
void DrawIndexed(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) override;
|
||||
void DrawModel(GLSprite *spr, FRenderState &state) override;
|
||||
|
||||
void SetDepthMask(bool on) override;
|
||||
void SetDepthFunc(int func) override;
|
||||
void EnableDrawBufferAttachments(bool on) override;
|
||||
|
||||
void StartScene();
|
||||
|
||||
// Sprite drawer
|
||||
void DrawSprite(GLSprite *sprite, int pass);
|
||||
void DrawPSprite(HUDSprite *huds);
|
||||
void DrawPlayerSprites(bool hudModelStep);
|
||||
|
||||
|
|
|
@ -168,8 +168,6 @@ void FDrawInfo::RenderScene(int recursion)
|
|||
gl_RenderState.AlphaFunc(Alpha_GEqual, 0.f);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
int pass = GLPASS_ALL;
|
||||
|
||||
gl_RenderState.EnableTexture(gl_texture);
|
||||
gl_RenderState.EnableBrightmap(true);
|
||||
drawlists[GLDL_PLAINWALLS].DrawWalls(this, gl_RenderState, false);
|
||||
|
@ -189,7 +187,7 @@ void FDrawInfo::RenderScene(int recursion)
|
|||
gl_RenderState.ClearDepthBias();
|
||||
}
|
||||
|
||||
drawlists[GLDL_MODELS].Draw(this, gl_RenderState, false, pass);
|
||||
drawlists[GLDL_MODELS].Draw(this, gl_RenderState, false);
|
||||
|
||||
gl_RenderState.SetRenderStyle(STYLE_Translucent);
|
||||
|
||||
|
@ -215,7 +213,7 @@ void FDrawInfo::RenderTranslucent()
|
|||
gl_RenderState.SetRenderStyle(STYLE_Translucent);
|
||||
|
||||
gl_RenderState.EnableBrightmap(true);
|
||||
drawlists[GLDL_TRANSLUCENTBORDER].Draw(this, gl_RenderState, true, GLPASS_TRANSLUCENT);
|
||||
drawlists[GLDL_TRANSLUCENTBORDER].Draw(this, gl_RenderState, true);
|
||||
glDepthMask(false);
|
||||
DrawSorted(GLDL_TRANSLUCENT);
|
||||
gl_RenderState.EnableBrightmap(false);
|
||||
|
|
|
@ -1,316 +0,0 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2002-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/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
/*
|
||||
** gl_sprite.cpp
|
||||
** Sprite/Particle rendering
|
||||
**
|
||||
*/
|
||||
|
||||
#include "gl_load/gl_system.h"
|
||||
#include "p_local.h"
|
||||
#include "p_effect.h"
|
||||
#include "g_level.h"
|
||||
#include "doomstat.h"
|
||||
#include "r_defs.h"
|
||||
#include "r_sky.h"
|
||||
#include "r_utility.h"
|
||||
#include "a_pickups.h"
|
||||
#include "d_player.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "events.h"
|
||||
#include "actorinlines.h"
|
||||
#include "r_data/r_vanillatrans.h"
|
||||
|
||||
#include "gl_load/gl_interface.h"
|
||||
#include "hwrenderer/utility/hw_cvars.h"
|
||||
#include "hwrenderer/scene/hw_drawstructs.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/models/gl_models.h"
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
#include "hwrenderer/utility/hw_lighting.h"
|
||||
|
||||
extern uint32_t r_renderercaps;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FDrawInfo::DrawSprite(GLSprite *sprite, int pass)
|
||||
{
|
||||
auto RenderStyle = sprite->RenderStyle;
|
||||
|
||||
bool additivefog = false;
|
||||
bool foglayer = false;
|
||||
int rel = sprite->fullbright? 0 : getExtraLight();
|
||||
auto &vp = Viewpoint;
|
||||
|
||||
if (pass==GLPASS_TRANSLUCENT)
|
||||
{
|
||||
// The translucent pass requires special setup for the various modes.
|
||||
|
||||
// for special render styles brightmaps would not look good - especially for subtractive.
|
||||
if (RenderStyle.BlendOp != STYLEOP_Add)
|
||||
{
|
||||
gl_RenderState.EnableBrightmap(false);
|
||||
}
|
||||
|
||||
// Optionally use STYLE_ColorBlend in place of STYLE_Add for fullbright items.
|
||||
if (RenderStyle == LegacyRenderStyles[STYLE_Add] && sprite->trans > 1.f - FLT_EPSILON &&
|
||||
gl_usecolorblending && !isFullbrightScene() && sprite->actor &&
|
||||
sprite->fullbright && sprite->gltexture && !sprite->gltexture->tex->GetTranslucency())
|
||||
{
|
||||
RenderStyle = LegacyRenderStyles[STYLE_ColorBlend];
|
||||
}
|
||||
|
||||
gl_RenderState.SetRenderStyle(RenderStyle);
|
||||
gl_RenderState.SetTextureMode(RenderStyle);
|
||||
|
||||
if (sprite->hw_styleflags == STYLEHW_NoAlphaTest)
|
||||
{
|
||||
gl_RenderState.AlphaFunc(Alpha_GEqual, 0.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_RenderState.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
|
||||
}
|
||||
|
||||
if (RenderStyle.BlendOp == STYLEOP_Shadow)
|
||||
{
|
||||
float fuzzalpha=0.44f;
|
||||
float minalpha=0.1f;
|
||||
|
||||
// fog + fuzz don't work well without some fiddling with the alpha value!
|
||||
if (!sprite->Colormap.FadeColor.isBlack())
|
||||
{
|
||||
float dist=Dist2(vp.Pos.X, vp.Pos.Y, sprite->x, sprite->y);
|
||||
int fogd = hw_GetFogDensity(sprite->lightlevel, sprite->Colormap.FadeColor, sprite->Colormap.FogDensity, sprite->Colormap.BlendFactor);
|
||||
|
||||
// this value was determined by trial and error and is scale dependent!
|
||||
float factor = 0.05f + exp(-fogd*dist / 62500.f);
|
||||
fuzzalpha*=factor;
|
||||
minalpha*=factor;
|
||||
}
|
||||
|
||||
gl_RenderState.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
|
||||
gl_RenderState.SetColor(0.2f,0.2f,0.2f,fuzzalpha, sprite->Colormap.Desaturation);
|
||||
additivefog = true;
|
||||
sprite->lightlist = nullptr; // the fuzz effect does not use the sector's light level so splitting is not needed.
|
||||
}
|
||||
else if (RenderStyle.BlendOp == STYLEOP_Add && RenderStyle.DestAlpha == STYLEALPHA_One)
|
||||
{
|
||||
additivefog = true;
|
||||
}
|
||||
}
|
||||
else if (sprite->modelframe == nullptr)
|
||||
{
|
||||
// This still needs to set the texture mode. As blend mode it will always use GL_ONE/GL_ZERO
|
||||
gl_RenderState.SetTextureMode(RenderStyle);
|
||||
gl_RenderState.SetDepthBias(-1, -128);
|
||||
}
|
||||
if (RenderStyle.BlendOp != STYLEOP_Shadow)
|
||||
{
|
||||
if (level.HasDynamicLights && !isFullbrightScene() && !sprite->fullbright)
|
||||
{
|
||||
if ( sprite->dynlightindex == -1) // only set if we got no light buffer index. This covers all cases where sprite lighting is used.
|
||||
{
|
||||
float out[3];
|
||||
GetDynSpriteLight(gl_light_sprites ? sprite->actor : nullptr, gl_light_particles ? sprite->particle : nullptr, out);
|
||||
gl_RenderState.SetDynLight(out[0], out[1], out[2]);
|
||||
}
|
||||
}
|
||||
sector_t *cursec = sprite->actor ? sprite->actor->Sector : sprite->particle ? sprite->particle->subsector->sector : nullptr;
|
||||
if (cursec != nullptr)
|
||||
{
|
||||
const PalEntry finalcol = sprite->fullbright
|
||||
? sprite->ThingColor
|
||||
: sprite->ThingColor.Modulate(cursec->SpecialColors[sector_t::sprites]);
|
||||
|
||||
gl_RenderState.SetObjectColor(finalcol);
|
||||
}
|
||||
SetColor(sprite->lightlevel, rel, sprite->Colormap, sprite->trans);
|
||||
}
|
||||
|
||||
|
||||
if (sprite->Colormap.FadeColor.isBlack()) sprite->foglevel = sprite->lightlevel;
|
||||
|
||||
if (RenderStyle.Flags & STYLEF_FadeToBlack)
|
||||
{
|
||||
sprite->Colormap.FadeColor=0;
|
||||
additivefog = true;
|
||||
}
|
||||
|
||||
if (RenderStyle.BlendOp == STYLEOP_RevSub || RenderStyle.BlendOp == STYLEOP_Sub)
|
||||
{
|
||||
if (!sprite->modelframe)
|
||||
{
|
||||
// non-black fog with subtractive style needs special treatment
|
||||
if (!sprite->Colormap.FadeColor.isBlack())
|
||||
{
|
||||
foglayer = true;
|
||||
// Due to the two-layer approach we need to force an alpha test that lets everything pass
|
||||
gl_RenderState.AlphaFunc(Alpha_Greater, 0);
|
||||
}
|
||||
}
|
||||
else RenderStyle.BlendOp = STYLEOP_Fuzz; // subtractive with models is not going to work.
|
||||
}
|
||||
|
||||
if (!foglayer) SetFog(sprite->foglevel, rel, &sprite->Colormap, additivefog);
|
||||
else
|
||||
{
|
||||
gl_RenderState.EnableFog(false);
|
||||
gl_RenderState.SetFog(0, 0);
|
||||
}
|
||||
|
||||
if (sprite->gltexture) gl_RenderState.ApplyMaterial(sprite->gltexture, CLAMP_XY, sprite->translation, sprite->OverrideShader);
|
||||
else if (!sprite->modelframe) gl_RenderState.EnableTexture(false);
|
||||
|
||||
//SetColor(lightlevel, rel, Colormap, trans);
|
||||
|
||||
unsigned int iter = sprite->lightlist? sprite->lightlist->Size() : 1;
|
||||
bool clipping = false;
|
||||
auto lightlist = sprite->lightlist;
|
||||
if (lightlist || sprite->topclip != LARGE_VALUE || sprite->bottomclip != -LARGE_VALUE)
|
||||
{
|
||||
clipping = true;
|
||||
gl_RenderState.EnableSplit(true);
|
||||
}
|
||||
|
||||
secplane_t bottomp = { { 0, 0, -1. }, sprite->bottomclip };
|
||||
secplane_t topp = { { 0, 0, -1. }, sprite->topclip };
|
||||
for (unsigned i = 0; i < iter; i++)
|
||||
{
|
||||
if (lightlist)
|
||||
{
|
||||
// set up the light slice
|
||||
secplane_t *topplane = i == 0 ? &topp : &(*lightlist)[i].plane;
|
||||
secplane_t *lowplane = i == (*lightlist).Size() - 1 ? &bottomp : &(*lightlist)[i + 1].plane;
|
||||
|
||||
int thislight = (*lightlist)[i].caster != nullptr ? hw_ClampLight(*(*lightlist)[i].p_lightlevel) : sprite->lightlevel;
|
||||
int thisll = sprite->actor == nullptr? thislight : (uint8_t)sprite->actor->Sector->CheckSpriteGlow(thislight, sprite->actor->InterpolatedPosition(vp.TicFrac));
|
||||
|
||||
FColormap thiscm;
|
||||
thiscm.CopyFog(sprite->Colormap);
|
||||
thiscm.CopyFrom3DLight(&(*lightlist)[i]);
|
||||
if (level.flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING)
|
||||
{
|
||||
thiscm.Decolorize();
|
||||
}
|
||||
|
||||
SetColor(thisll, rel, thiscm, sprite->trans);
|
||||
if (!foglayer)
|
||||
{
|
||||
SetFog(thislight, rel, &thiscm, additivefog);
|
||||
}
|
||||
gl_RenderState.SetSplitPlanes(*topplane, *lowplane);
|
||||
}
|
||||
else if (clipping)
|
||||
{
|
||||
gl_RenderState.SetSplitPlanes(topp, bottomp);
|
||||
}
|
||||
|
||||
if (!sprite->modelframe)
|
||||
{
|
||||
gl_RenderState.Apply();
|
||||
|
||||
gl_RenderState.SetNormal(0, 0, 0);
|
||||
|
||||
if (screen->BuffersArePersistent())
|
||||
{
|
||||
sprite->CreateVertices(this);
|
||||
}
|
||||
if (sprite->polyoffset)
|
||||
{
|
||||
gl_RenderState.SetDepthBias(-1, -128);
|
||||
}
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, sprite->vertexindex, 4);
|
||||
|
||||
if (foglayer)
|
||||
{
|
||||
// If we get here we know that we have colored fog and no fixed colormap.
|
||||
SetFog(sprite->foglevel, rel, &sprite->Colormap, additivefog);
|
||||
gl_RenderState.SetTextureMode(TM_FOGLAYER);
|
||||
gl_RenderState.SetRenderStyle(STYLE_Translucent);
|
||||
gl_RenderState.Apply();
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, sprite->vertexindex, 4);
|
||||
gl_RenderState.SetTextureMode(TM_NORMAL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FGLModelRenderer renderer(this, sprite->dynlightindex);
|
||||
renderer.RenderModel(sprite->x, sprite->y, sprite->z, sprite->modelframe, sprite->actor, vp.TicFrac);
|
||||
}
|
||||
}
|
||||
|
||||
if (clipping)
|
||||
{
|
||||
gl_RenderState.EnableSplit(false);
|
||||
}
|
||||
|
||||
if (pass==GLPASS_TRANSLUCENT)
|
||||
{
|
||||
gl_RenderState.EnableBrightmap(true);
|
||||
gl_RenderState.SetRenderStyle(STYLE_Translucent);
|
||||
gl_RenderState.SetTextureMode(TM_NORMAL);
|
||||
if (sprite->actor != nullptr && (sprite->actor->renderflags & RF_SPRITETYPEMASK) == RF_FLATSPRITE)
|
||||
{
|
||||
gl_RenderState.ClearDepthBias();
|
||||
}
|
||||
}
|
||||
else if (sprite->modelframe == nullptr)
|
||||
{
|
||||
gl_RenderState.ClearDepthBias();
|
||||
}
|
||||
|
||||
gl_RenderState.SetObjectColor(0xffffffff);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
gl_RenderState.SetDynLight(0,0,0);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void FDrawInfo::AddSprite(GLSprite *sprite, bool translucent)
|
||||
{
|
||||
int list;
|
||||
// [BB] Allow models to be drawn in the GLDL_TRANSLUCENT pass.
|
||||
if (translucent || sprite->actor == nullptr || (!sprite->modelframe && (sprite->actor->renderflags & RF_SPRITETYPEMASK) != RF_WALLSPRITE))
|
||||
{
|
||||
list = GLDL_TRANSLUCENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
list = GLDL_MODELS;
|
||||
}
|
||||
|
||||
auto newsprt = drawlists[list].NewSprite();
|
||||
*newsprt = *sprite;
|
||||
}
|
||||
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
#include "gl_load/gl_interface.h"
|
||||
#include "hwrenderer/utility/hw_cvars.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
|
|
|
@ -294,8 +294,6 @@ public:
|
|||
|
||||
void DrawDecals(FRenderState &state, TArray<GLDecal *> &decals);
|
||||
|
||||
virtual void DrawSprite(GLSprite *sprite, int pass) = 0;
|
||||
|
||||
void ProcessLowerMinisegs(TArray<seg_t *> &lowersegs);
|
||||
virtual void AddSubsectorToPortal(FSectorPortalGroup *portal, subsector_t *sub) = 0;
|
||||
|
||||
|
@ -315,6 +313,9 @@ public:
|
|||
|
||||
virtual void Draw(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) = 0;
|
||||
virtual void DrawIndexed(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) = 0;
|
||||
virtual void DrawModel(GLSprite *spr, FRenderState &state) = 0;
|
||||
|
||||
|
||||
|
||||
// Immediate render state change commands. These only change infrequently and should not clutter the render state.
|
||||
virtual void SetDepthMask(bool on) = 0;
|
||||
|
|
|
@ -771,7 +771,7 @@ GLSprite *HWDrawList::NewSprite()
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void HWDrawList::DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, int pass, int i, bool trans)
|
||||
void HWDrawList::DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, int i)
|
||||
{
|
||||
switch(drawitems[i].rendertype)
|
||||
{
|
||||
|
@ -797,7 +797,7 @@ void HWDrawList::DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, i
|
|||
{
|
||||
GLSprite * s= sprites[drawitems[i].index];
|
||||
RenderSprite.Clock();
|
||||
di->DrawSprite(s, pass);
|
||||
s->DrawSprite(di, state, translucent);
|
||||
RenderSprite.Unclock();
|
||||
}
|
||||
break;
|
||||
|
@ -809,11 +809,11 @@ void HWDrawList::DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, i
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void HWDrawList::Draw(HWDrawInfo *di, FRenderState &state, bool translucent, int pass, bool trans)
|
||||
void HWDrawList::Draw(HWDrawInfo *di, FRenderState &state, bool translucent)
|
||||
{
|
||||
for (unsigned i = 0; i < drawitems.Size(); i++)
|
||||
{
|
||||
DoDraw(di, state, translucent, pass, i, trans);
|
||||
DoDraw(di, state, translucent, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -103,8 +103,8 @@ public:
|
|||
SortNode * DoSort(HWDrawInfo *di, SortNode * head);
|
||||
void Sort(HWDrawInfo *di);
|
||||
|
||||
void DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, int pass, int i, bool trans);
|
||||
void Draw(HWDrawInfo *di, FRenderState &state, bool translucent, int pass, bool trans = false);
|
||||
void DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, int i);
|
||||
void Draw(HWDrawInfo *di, FRenderState &state, bool translucent);
|
||||
void DrawWalls(HWDrawInfo *di, FRenderState &state, bool translucent);
|
||||
void DrawFlats(HWDrawInfo *di, FRenderState &state, bool translucent);
|
||||
|
||||
|
|
|
@ -401,12 +401,14 @@ public:
|
|||
|
||||
public:
|
||||
|
||||
GLSprite() {}
|
||||
GLSprite() = default;
|
||||
void CreateVertices(HWDrawInfo *di);
|
||||
void PutSprite(HWDrawInfo *di, bool translucent);
|
||||
void Process(HWDrawInfo *di, AActor* thing,sector_t * sector, area_t in_area, int thruportal = false);
|
||||
void ProcessParticle (HWDrawInfo *di, particle_t *particle, sector_t *sector);//, int shade, int fakeside)
|
||||
|
||||
void DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent);
|
||||
|
||||
GLSprite(const GLSprite &other)
|
||||
{
|
||||
memcpy(this, &other, sizeof(GLSprite));
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "hwrenderer/utility/hw_lighting.h"
|
||||
#include "hwrenderer/textures/hw_material.h"
|
||||
#include "hwrenderer/dynlights/hw_dynlightdata.h"
|
||||
#include "hw_renderstate.h"
|
||||
|
||||
extern TArray<spritedef_t> sprites;
|
||||
extern TArray<spriteframe_t> SpriteFrames;
|
||||
|
@ -63,6 +64,238 @@ EXTERN_CVAR(Bool, r_debug_disable_vis_filter)
|
|||
EXTERN_CVAR(Float, transsouls)
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent)
|
||||
{
|
||||
bool additivefog = false;
|
||||
bool foglayer = false;
|
||||
int rel = fullbright ? 0 : getExtraLight();
|
||||
auto &vp = di->Viewpoint;
|
||||
|
||||
if (translucent)
|
||||
{
|
||||
// The translucent pass requires special setup for the various modes.
|
||||
|
||||
// for special render styles brightmaps would not look good - especially for subtractive.
|
||||
if (RenderStyle.BlendOp != STYLEOP_Add)
|
||||
{
|
||||
state.EnableBrightmap(false);
|
||||
}
|
||||
|
||||
// Optionally use STYLE_ColorBlend in place of STYLE_Add for fullbright items.
|
||||
if (RenderStyle == LegacyRenderStyles[STYLE_Add] && trans > 1.f - FLT_EPSILON &&
|
||||
gl_usecolorblending && !di->isFullbrightScene() && actor &&
|
||||
fullbright && gltexture && !gltexture->tex->GetTranslucency())
|
||||
{
|
||||
RenderStyle = LegacyRenderStyles[STYLE_ColorBlend];
|
||||
}
|
||||
|
||||
state.SetRenderStyle(RenderStyle);
|
||||
state.SetTextureMode(RenderStyle);
|
||||
|
||||
if (hw_styleflags == STYLEHW_NoAlphaTest)
|
||||
{
|
||||
state.AlphaFunc(Alpha_GEqual, 0.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
state.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
|
||||
}
|
||||
|
||||
if (RenderStyle.BlendOp == STYLEOP_Shadow)
|
||||
{
|
||||
float fuzzalpha = 0.44f;
|
||||
float minalpha = 0.1f;
|
||||
|
||||
// fog + fuzz don't work well without some fiddling with the alpha value!
|
||||
if (!Colormap.FadeColor.isBlack())
|
||||
{
|
||||
float dist = Dist2(vp.Pos.X, vp.Pos.Y, x, y);
|
||||
int fogd = hw_GetFogDensity(lightlevel, Colormap.FadeColor, Colormap.FogDensity, Colormap.BlendFactor);
|
||||
|
||||
// this value was determined by trial and error and is scale dependent!
|
||||
float factor = 0.05f + exp(-fogd * dist / 62500.f);
|
||||
fuzzalpha *= factor;
|
||||
minalpha *= factor;
|
||||
}
|
||||
|
||||
state.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
|
||||
state.SetColor(0.2f, 0.2f, 0.2f, fuzzalpha, Colormap.Desaturation);
|
||||
additivefog = true;
|
||||
lightlist = nullptr; // the fuzz effect does not use the sector's light level so splitting is not needed.
|
||||
}
|
||||
else if (RenderStyle.BlendOp == STYLEOP_Add && RenderStyle.DestAlpha == STYLEALPHA_One)
|
||||
{
|
||||
additivefog = true;
|
||||
}
|
||||
}
|
||||
else if (modelframe == nullptr)
|
||||
{
|
||||
// This still needs to set the texture mode. As blend mode it will always use GL_ONE/GL_ZERO
|
||||
state.SetTextureMode(RenderStyle);
|
||||
state.SetDepthBias(-1, -128);
|
||||
}
|
||||
if (RenderStyle.BlendOp != STYLEOP_Shadow)
|
||||
{
|
||||
if (level.HasDynamicLights && !di->isFullbrightScene() && !fullbright)
|
||||
{
|
||||
if (dynlightindex == -1) // only set if we got no light buffer index. This covers all cases where sprite lighting is used.
|
||||
{
|
||||
float out[3];
|
||||
di->GetDynSpriteLight(gl_light_sprites ? actor : nullptr, gl_light_particles ? particle : nullptr, out);
|
||||
state.SetDynLight(out[0], out[1], out[2]);
|
||||
}
|
||||
}
|
||||
sector_t *cursec = actor ? actor->Sector : particle ? particle->subsector->sector : nullptr;
|
||||
if (cursec != nullptr)
|
||||
{
|
||||
const PalEntry finalcol = fullbright
|
||||
? ThingColor
|
||||
: ThingColor.Modulate(cursec->SpecialColors[sector_t::sprites]);
|
||||
|
||||
state.SetObjectColor(finalcol);
|
||||
}
|
||||
state.SetColor(lightlevel, rel, di->isFullbrightScene(), Colormap, trans);
|
||||
}
|
||||
|
||||
|
||||
if (Colormap.FadeColor.isBlack()) foglevel = lightlevel;
|
||||
|
||||
if (RenderStyle.Flags & STYLEF_FadeToBlack)
|
||||
{
|
||||
Colormap.FadeColor = 0;
|
||||
additivefog = true;
|
||||
}
|
||||
|
||||
if (RenderStyle.BlendOp == STYLEOP_RevSub || RenderStyle.BlendOp == STYLEOP_Sub)
|
||||
{
|
||||
if (!modelframe)
|
||||
{
|
||||
// non-black fog with subtractive style needs special treatment
|
||||
if (!Colormap.FadeColor.isBlack())
|
||||
{
|
||||
foglayer = true;
|
||||
// Due to the two-layer approach we need to force an alpha test that lets everything pass
|
||||
state.AlphaFunc(Alpha_Greater, 0);
|
||||
}
|
||||
}
|
||||
else RenderStyle.BlendOp = STYLEOP_Fuzz; // subtractive with models is not going to work.
|
||||
}
|
||||
|
||||
if (!foglayer) state.SetFog(foglevel, rel, di->isFullbrightScene(), &Colormap, additivefog);
|
||||
else
|
||||
{
|
||||
state.EnableFog(false);
|
||||
state.SetFog(0, 0);
|
||||
}
|
||||
|
||||
if (gltexture) state.SetMaterial(gltexture, CLAMP_XY, translation, OverrideShader);
|
||||
else if (!modelframe) state.EnableTexture(false);
|
||||
|
||||
//SetColor(lightlevel, rel, Colormap, trans);
|
||||
|
||||
unsigned int iter = lightlist ? lightlist->Size() : 1;
|
||||
bool clipping = false;
|
||||
if (lightlist || topclip != LARGE_VALUE || bottomclip != -LARGE_VALUE)
|
||||
{
|
||||
clipping = true;
|
||||
state.EnableSplit(true);
|
||||
}
|
||||
|
||||
secplane_t bottomp = { { 0, 0, -1. }, bottomclip };
|
||||
secplane_t topp = { { 0, 0, -1. }, topclip };
|
||||
for (unsigned i = 0; i < iter; i++)
|
||||
{
|
||||
if (lightlist)
|
||||
{
|
||||
// set up the light slice
|
||||
secplane_t *topplane = i == 0 ? &topp : &(*lightlist)[i].plane;
|
||||
secplane_t *lowplane = i == (*lightlist).Size() - 1 ? &bottomp : &(*lightlist)[i + 1].plane;
|
||||
|
||||
int thislight = (*lightlist)[i].caster != nullptr ? hw_ClampLight(*(*lightlist)[i].p_lightlevel) : lightlevel;
|
||||
int thisll = actor == nullptr ? thislight : (uint8_t)actor->Sector->CheckSpriteGlow(thislight, actor->InterpolatedPosition(vp.TicFrac));
|
||||
|
||||
FColormap thiscm;
|
||||
thiscm.CopyFog(Colormap);
|
||||
thiscm.CopyFrom3DLight(&(*lightlist)[i]);
|
||||
if (level.flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING)
|
||||
{
|
||||
thiscm.Decolorize();
|
||||
}
|
||||
|
||||
state.SetColor(thisll, rel, di->isFullbrightScene(), thiscm, trans);
|
||||
if (!foglayer)
|
||||
{
|
||||
state.SetFog(thislight, rel, di->isFullbrightScene(), &thiscm, additivefog);
|
||||
}
|
||||
state.SetSplitPlanes(*topplane, *lowplane);
|
||||
}
|
||||
else if (clipping)
|
||||
{
|
||||
state.SetSplitPlanes(topp, bottomp);
|
||||
}
|
||||
|
||||
if (!modelframe)
|
||||
{
|
||||
state.SetNormal(0, 0, 0);
|
||||
|
||||
if (screen->BuffersArePersistent())
|
||||
{
|
||||
CreateVertices(di);
|
||||
}
|
||||
if (polyoffset)
|
||||
{
|
||||
state.SetDepthBias(-1, -128);
|
||||
}
|
||||
|
||||
di->Draw(DT_TriangleStrip, state, vertexindex, 4);
|
||||
|
||||
if (foglayer)
|
||||
{
|
||||
// If we get here we know that we have colored fog and no fixed colormap.
|
||||
state.SetFog(foglevel, rel, false, &Colormap, additivefog);
|
||||
state.SetTextureMode(TM_FOGLAYER);
|
||||
state.SetRenderStyle(STYLE_Translucent);
|
||||
di->Draw(DT_TriangleStrip, state, vertexindex, 4);
|
||||
state.SetTextureMode(TM_NORMAL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
di->DrawModel(this, state);
|
||||
}
|
||||
}
|
||||
|
||||
if (clipping)
|
||||
{
|
||||
state.EnableSplit(false);
|
||||
}
|
||||
|
||||
if (translucent)
|
||||
{
|
||||
state.EnableBrightmap(true);
|
||||
state.SetRenderStyle(STYLE_Translucent);
|
||||
state.SetTextureMode(TM_NORMAL);
|
||||
if (actor != nullptr && (actor->renderflags & RF_SPRITETYPEMASK) == RF_FLATSPRITE)
|
||||
{
|
||||
state.ClearDepthBias();
|
||||
}
|
||||
}
|
||||
else if (modelframe == nullptr)
|
||||
{
|
||||
state.ClearDepthBias();
|
||||
}
|
||||
|
||||
state.SetObjectColor(0xffffffff);
|
||||
state.EnableTexture(true);
|
||||
state.SetDynLight(0, 0, 0);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue