mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 07:11:54 +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.cpp
|
||||||
textures/hires/xbr/xbrz_old.cpp
|
textures/hires/xbr/xbrz_old.cpp
|
||||||
gl/scene/gl_drawinfo.cpp
|
gl/scene/gl_drawinfo.cpp
|
||||||
gl/scene/gl_sprite.cpp
|
|
||||||
gl/scene/gl_skydome.cpp
|
gl/scene/gl_skydome.cpp
|
||||||
gl/scene/gl_weapon.cpp
|
gl/scene/gl_weapon.cpp
|
||||||
gl/scene/gl_scene.cpp
|
gl/scene/gl_scene.cpp
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "gl/scene/gl_portal.h"
|
#include "gl/scene/gl_portal.h"
|
||||||
#include "gl/renderer/gl_renderstate.h"
|
#include "gl/renderer/gl_renderstate.h"
|
||||||
#include "gl/dynlights/gl_lightbuffer.h"
|
#include "gl/dynlights/gl_lightbuffer.h"
|
||||||
|
#include "gl/models/gl_models.h"
|
||||||
|
|
||||||
class FDrawInfoList
|
class FDrawInfoList
|
||||||
{
|
{
|
||||||
|
@ -90,13 +91,13 @@ void FDrawInfo::DoDrawSorted(HWDrawList *dl, SortNode * head)
|
||||||
DoDrawSorted(dl, head->left);
|
DoDrawSorted(dl, head->left);
|
||||||
gl_RenderState.SetClipSplit(clipsplit);
|
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)
|
if (head->equal)
|
||||||
{
|
{
|
||||||
SortNode * ehead=head->equal;
|
SortNode * ehead=head->equal;
|
||||||
while (ehead)
|
while (ehead)
|
||||||
{
|
{
|
||||||
dl->DoDraw(this, gl_RenderState, true, GLPASS_TRANSLUCENT, ehead->itemindex, true);
|
dl->DoDraw(this, gl_RenderState, true, ehead->itemindex);
|
||||||
ehead=ehead->equal;
|
ehead=ehead->equal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,6 +299,12 @@ void FDrawInfo::DrawIndexed(EDrawType dt, FRenderState &state, int index, int co
|
||||||
drawcalls.Unclock();
|
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)
|
void FDrawInfo::SetDepthMask(bool on)
|
||||||
{
|
{
|
||||||
glDepthMask(on);
|
glDepthMask(on);
|
||||||
|
@ -357,3 +364,26 @@ void FDrawInfo::AddFlat(GLFlat *flat, bool fog)
|
||||||
*newflat = *flat;
|
*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,
|
GLDL_TYPES,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Drawpasses
|
|
||||||
{
|
|
||||||
GLPASS_ALL, // Main pass with dynamic lights
|
|
||||||
GLPASS_TRANSLUCENT, // Draws translucent objects
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FDrawInfo : public HWDrawInfo
|
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 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 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 SetDepthMask(bool on) override;
|
||||||
void SetDepthFunc(int func) override;
|
void SetDepthFunc(int func) override;
|
||||||
void EnableDrawBufferAttachments(bool on) override;
|
void EnableDrawBufferAttachments(bool on) override;
|
||||||
|
|
||||||
void StartScene();
|
void StartScene();
|
||||||
|
|
||||||
// Sprite drawer
|
|
||||||
void DrawSprite(GLSprite *sprite, int pass);
|
|
||||||
void DrawPSprite(HUDSprite *huds);
|
void DrawPSprite(HUDSprite *huds);
|
||||||
void DrawPlayerSprites(bool hudModelStep);
|
void DrawPlayerSprites(bool hudModelStep);
|
||||||
|
|
||||||
|
|
|
@ -168,8 +168,6 @@ void FDrawInfo::RenderScene(int recursion)
|
||||||
gl_RenderState.AlphaFunc(Alpha_GEqual, 0.f);
|
gl_RenderState.AlphaFunc(Alpha_GEqual, 0.f);
|
||||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||||
|
|
||||||
int pass = GLPASS_ALL;
|
|
||||||
|
|
||||||
gl_RenderState.EnableTexture(gl_texture);
|
gl_RenderState.EnableTexture(gl_texture);
|
||||||
gl_RenderState.EnableBrightmap(true);
|
gl_RenderState.EnableBrightmap(true);
|
||||||
drawlists[GLDL_PLAINWALLS].DrawWalls(this, gl_RenderState, false);
|
drawlists[GLDL_PLAINWALLS].DrawWalls(this, gl_RenderState, false);
|
||||||
|
@ -189,7 +187,7 @@ void FDrawInfo::RenderScene(int recursion)
|
||||||
gl_RenderState.ClearDepthBias();
|
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);
|
gl_RenderState.SetRenderStyle(STYLE_Translucent);
|
||||||
|
|
||||||
|
@ -215,7 +213,7 @@ void FDrawInfo::RenderTranslucent()
|
||||||
gl_RenderState.SetRenderStyle(STYLE_Translucent);
|
gl_RenderState.SetRenderStyle(STYLE_Translucent);
|
||||||
|
|
||||||
gl_RenderState.EnableBrightmap(true);
|
gl_RenderState.EnableBrightmap(true);
|
||||||
drawlists[GLDL_TRANSLUCENTBORDER].Draw(this, gl_RenderState, true, GLPASS_TRANSLUCENT);
|
drawlists[GLDL_TRANSLUCENTBORDER].Draw(this, gl_RenderState, true);
|
||||||
glDepthMask(false);
|
glDepthMask(false);
|
||||||
DrawSorted(GLDL_TRANSLUCENT);
|
DrawSorted(GLDL_TRANSLUCENT);
|
||||||
gl_RenderState.EnableBrightmap(false);
|
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 "gl_load/gl_interface.h"
|
||||||
#include "hwrenderer/utility/hw_cvars.h"
|
#include "hwrenderer/utility/hw_cvars.h"
|
||||||
#include "gl/renderer/gl_renderstate.h"
|
|
||||||
#include "gl/renderer/gl_renderer.h"
|
#include "gl/renderer/gl_renderer.h"
|
||||||
#include "gl/data/gl_vertexbuffer.h"
|
#include "gl/data/gl_vertexbuffer.h"
|
||||||
#include "gl/dynlights/gl_lightbuffer.h"
|
#include "gl/dynlights/gl_lightbuffer.h"
|
||||||
|
|
|
@ -294,8 +294,6 @@ public:
|
||||||
|
|
||||||
void DrawDecals(FRenderState &state, TArray<GLDecal *> &decals);
|
void DrawDecals(FRenderState &state, TArray<GLDecal *> &decals);
|
||||||
|
|
||||||
virtual void DrawSprite(GLSprite *sprite, int pass) = 0;
|
|
||||||
|
|
||||||
void ProcessLowerMinisegs(TArray<seg_t *> &lowersegs);
|
void ProcessLowerMinisegs(TArray<seg_t *> &lowersegs);
|
||||||
virtual void AddSubsectorToPortal(FSectorPortalGroup *portal, subsector_t *sub) = 0;
|
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 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 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.
|
// Immediate render state change commands. These only change infrequently and should not clutter the render state.
|
||||||
virtual void SetDepthMask(bool on) = 0;
|
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)
|
switch(drawitems[i].rendertype)
|
||||||
{
|
{
|
||||||
|
@ -797,7 +797,7 @@ void HWDrawList::DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, i
|
||||||
{
|
{
|
||||||
GLSprite * s= sprites[drawitems[i].index];
|
GLSprite * s= sprites[drawitems[i].index];
|
||||||
RenderSprite.Clock();
|
RenderSprite.Clock();
|
||||||
di->DrawSprite(s, pass);
|
s->DrawSprite(di, state, translucent);
|
||||||
RenderSprite.Unclock();
|
RenderSprite.Unclock();
|
||||||
}
|
}
|
||||||
break;
|
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++)
|
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);
|
SortNode * DoSort(HWDrawInfo *di, SortNode * head);
|
||||||
void Sort(HWDrawInfo *di);
|
void Sort(HWDrawInfo *di);
|
||||||
|
|
||||||
void DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, int pass, int i, bool trans);
|
void DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, int i);
|
||||||
void Draw(HWDrawInfo *di, FRenderState &state, bool translucent, int pass, bool trans = false);
|
void Draw(HWDrawInfo *di, FRenderState &state, bool translucent);
|
||||||
void DrawWalls(HWDrawInfo *di, FRenderState &state, bool translucent);
|
void DrawWalls(HWDrawInfo *di, FRenderState &state, bool translucent);
|
||||||
void DrawFlats(HWDrawInfo *di, FRenderState &state, bool translucent);
|
void DrawFlats(HWDrawInfo *di, FRenderState &state, bool translucent);
|
||||||
|
|
||||||
|
|
|
@ -401,12 +401,14 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GLSprite() {}
|
GLSprite() = default;
|
||||||
void CreateVertices(HWDrawInfo *di);
|
void CreateVertices(HWDrawInfo *di);
|
||||||
void PutSprite(HWDrawInfo *di, bool translucent);
|
void PutSprite(HWDrawInfo *di, bool translucent);
|
||||||
void Process(HWDrawInfo *di, AActor* thing,sector_t * sector, area_t in_area, int thruportal = false);
|
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 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)
|
GLSprite(const GLSprite &other)
|
||||||
{
|
{
|
||||||
memcpy(this, &other, sizeof(GLSprite));
|
memcpy(this, &other, sizeof(GLSprite));
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
#include "hwrenderer/utility/hw_lighting.h"
|
#include "hwrenderer/utility/hw_lighting.h"
|
||||||
#include "hwrenderer/textures/hw_material.h"
|
#include "hwrenderer/textures/hw_material.h"
|
||||||
#include "hwrenderer/dynlights/hw_dynlightdata.h"
|
#include "hwrenderer/dynlights/hw_dynlightdata.h"
|
||||||
|
#include "hw_renderstate.h"
|
||||||
|
|
||||||
extern TArray<spritedef_t> sprites;
|
extern TArray<spritedef_t> sprites;
|
||||||
extern TArray<spriteframe_t> SpriteFrames;
|
extern TArray<spriteframe_t> SpriteFrames;
|
||||||
|
@ -63,6 +64,238 @@ EXTERN_CVAR(Bool, r_debug_disable_vis_filter)
|
||||||
EXTERN_CVAR(Float, transsouls)
|
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