- removed the Softpoly backend.

Its only relevant use case has been to use the software renderer on hardware not capable of OpenGL 3.3, but a large chunk of that can now be serviced with GLES.
In addition it has ceased further development and has not received any of the recent 2D render features which further reduces its viability.
This commit is contained in:
Christoph Oelckers 2022-07-28 10:31:56 +02:00
commit 93e934c8d0
58 changed files with 25 additions and 7282 deletions

View file

@ -53,7 +53,6 @@
#include "r_thread.h"
#include "swrenderer/scene/r_light.h"
#include "playsim/a_dynlight.h"
#include "polyrenderer/drawers/poly_thread.h"
CVAR(Bool, r_dynlights, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR(Bool, r_fuzzscale, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
@ -221,44 +220,6 @@ namespace swrenderer
/////////////////////////////////////////////////////////////////////////
void SWPixelFormatDrawers::DrawDepthColumn(const WallColumnDrawerArgs& args, float idepth)
{
int x, y, count;
auto rendertarget = args.Viewport()->RenderTarget;
if (rendertarget->IsBgra())
{
uint32_t* destorg = (uint32_t*)rendertarget->GetPixels();
destorg += viewwindowx + viewwindowy * rendertarget->GetPitch();
uint32_t* dest = (uint32_t*)args.Dest();
int offset = (int)(ptrdiff_t)(dest - destorg);
x = offset % rendertarget->GetPitch();
y = offset / rendertarget->GetPitch();
}
else
{
uint8_t* destorg = rendertarget->GetPixels();
destorg += viewwindowx + viewwindowy * rendertarget->GetPitch();
uint8_t* dest = (uint8_t*)args.Dest();
int offset = (int)(ptrdiff_t)(dest - destorg);
x = offset % rendertarget->GetPitch();
y = offset / rendertarget->GetPitch();
}
count = args.Count();
auto zbuffer = thread->Poly->depthstencil;
int pitch = zbuffer->Width();
float* values = zbuffer->DepthValues() + y * pitch + x;
int cnt = count;
float depth = idepth;
for (int i = 0; i < cnt; i++)
{
*values = depth;
values += pitch;
}
}
void SWPixelFormatDrawers::SetLights(WallColumnDrawerArgs& drawerargs, int x, int y1, const WallDrawerArgs& wallargs)
{
bool mirror = !!(wallargs.PortalMirrorFlags & RF_XFLIP);
@ -323,76 +284,4 @@ namespace swrenderer
}
}
/////////////////////////////////////////////////////////////////////////
void SWPixelFormatDrawers::DrawDepthSkyColumn(const SkyDrawerArgs &args, float idepth)
{
int x, y, count;
auto rendertarget = args.Viewport()->RenderTarget;
if (rendertarget->IsBgra())
{
uint32_t* destorg = (uint32_t*)rendertarget->GetPixels();
destorg += viewwindowx + viewwindowy * rendertarget->GetPitch();
uint32_t* dest = (uint32_t*)args.Dest();
int offset = (int)(ptrdiff_t)(dest - destorg);
x = offset % rendertarget->GetPitch();
y = offset / rendertarget->GetPitch();
}
else
{
uint8_t* destorg = rendertarget->GetPixels();
destorg += viewwindowx + viewwindowy * rendertarget->GetPitch();
uint8_t* dest = (uint8_t*)args.Dest();
int offset = (int)(ptrdiff_t)(dest - destorg);
x = offset % rendertarget->GetPitch();
y = offset / rendertarget->GetPitch();
}
count = args.Count();
auto zbuffer = thread->Poly->depthstencil;
int pitch = zbuffer->Width();
float* values = zbuffer->DepthValues() + y * pitch + x;
int cnt = count;
float depth = idepth;
for (int i = 0; i < cnt; i++)
{
*values = depth;
values += pitch;
}
}
void SWPixelFormatDrawers::DrawDepthSpan(const SpanDrawerArgs &args, float idepth1, float idepth2)
{
int y = args.DestY();
int x1 = args.DestX1();
int x2 = args.DestX2();
auto zbuffer = thread->Poly->depthstencil;
int pitch = zbuffer->Width();
float *values = zbuffer->DepthValues() + x1 + y * pitch;
int count = x2 - x1 + 1;
if (idepth1 == idepth2)
{
float depth = idepth1;
for (int i = 0; i < count; i++)
{
*values = depth;
values++;
}
}
else
{
float depth = idepth1;
float step = (idepth2 - idepth1) / (x2 - x1 + 1);
for (int i = 0; i < count; i++)
{
*values = depth;
values++;
depth += step;
}
}
}
}

View file

@ -94,10 +94,6 @@ namespace swrenderer
virtual void DrawFogBoundaryLine(const SpanDrawerArgs &args) = 0;
virtual void DrawParticleColumn(int x, int yl, int ycount, uint32_t fg, uint32_t alpha, uint32_t fracposx) = 0;
void DrawDepthColumn(const WallColumnDrawerArgs& args, float idepth);
void DrawDepthSkyColumn(const SkyDrawerArgs &args, float idepth);
void DrawDepthSpan(const SpanDrawerArgs &args, float idepth1, float idepth2);
void SetLights(WallColumnDrawerArgs& drawerargs, int x, int y1, const WallDrawerArgs& wallargs);
RenderThread* thread = nullptr;

View file

@ -3060,30 +3060,6 @@ namespace swrenderer
wpos += wstepX;
curlight += lightstep;
}
if (r_modelscene)
{
for (int x = x1; x < x2; x++)
{
int y1 = uwal[x];
int y2 = dwal[x];
if (y2 > y1)
{
int count = y2 - y1;
float w1 = 1.0f / wallargs.WallC.sz1;
float w2 = 1.0f / wallargs.WallC.sz2;
float t = (x - wallargs.WallC.sx1 + 0.5f) / (wallargs.WallC.sx2 - wallargs.WallC.sx1);
float wcol = w1 * (1.0f - t) + w2 * t;
float zcol = 1.0f / wcol;
float zbufferdepth = 1.0f / (zcol / wallargs.FocalTangent);
wallcolargs.SetDest(x, y1);
wallcolargs.SetCount(count);
DrawDepthColumn(wallcolargs, zbufferdepth);
}
}
}
}
template<typename DrawerT>

View file

@ -956,30 +956,6 @@ namespace swrenderer
wpos += wstepX;
curlight += lightstep;
}
if (r_modelscene)
{
for (int x = x1; x < x2; x++)
{
int y1 = uwal[x];
int y2 = dwal[x];
if (y2 > y1)
{
int count = y2 - y1;
float w1 = 1.0f / wallargs.WallC.sz1;
float w2 = 1.0f / wallargs.WallC.sz2;
float t = (x - wallargs.WallC.sx1 + 0.5f) / (wallargs.WallC.sx2 - wallargs.WallC.sx1);
float wcol = w1 * (1.0f - t) + w2 * t;
float zcol = 1.0f / wcol;
float zbufferdepth = 1.0f / (zcol / wallargs.FocalTangent);
wallcolargs.SetDest(x, y1);
wallcolargs.SetCount(count);
DrawDepthColumn(wallcolargs, zbufferdepth);
}
}
}
}
template<typename DrawerT>

View file

@ -270,8 +270,6 @@ namespace swrenderer
drawerargs.SetDestX2(x2);
drawerargs.DrawSpan(Thread);
if (r_modelscene)
drawerargs.DrawDepthSpan(Thread, zbufferdepth, zbufferdepth);
}
/////////////////////////////////////////////////////////////////////////

View file

@ -267,8 +267,6 @@ namespace swrenderer
else
drawerargs.DrawDoubleSkyColumn(Thread);
if (r_modelscene)
drawerargs.DrawDepthSkyColumn(Thread, 1.0f / 65536.0f);
}
void RenderSkyPlane::DrawSkyColumn(int start_x, int y1, int y2)

View file

@ -205,22 +205,5 @@ namespace swrenderer
void RenderSlopePlane::RenderLine(int y, int x1, int x2)
{
drawerargs.DrawTiltedSpan(Thread, y, x1, x2, plane_sz, plane_su, plane_sv, plane_shade, lightlevel, foggy, planelightfloat, pviewx, pviewy, basecolormap);
if (r_modelscene)
{
double viewZ = 1.0;
double viewX1 = Thread->Viewport->ScreenToViewX(x1, viewZ);
double viewX2 = Thread->Viewport->ScreenToViewX(x2 + 1, viewZ);
double viewY = Thread->Viewport->ScreenToViewY(y, viewZ);
// Find depth values for the span
float zbufferdepth1 = (float)(-planeD / (planeNormal | DVector3(viewX1, viewZ, viewY)));
float zbufferdepth2 = (float)(-planeD / (planeNormal | DVector3(viewX2, viewZ, viewY)));
drawerargs.SetDestX1(x1);
drawerargs.SetDestX2(x2);
drawerargs.SetDestY(Thread->Viewport.get(), y);
drawerargs.DrawDepthSpan(Thread, 1.0f / zbufferdepth1, 1.0f / zbufferdepth2);
}
}
}

View file

@ -34,7 +34,6 @@
#include "things/r_visiblespritelist.cpp"
#include "things/r_voxel.cpp"
#include "things/r_wallsprite.cpp"
#include "things/r_model.cpp"
#include "viewport/r_drawerargs.cpp"
#include "viewport/r_skydrawer.cpp"
#include "viewport/r_spandrawer.cpp"

View file

@ -53,7 +53,6 @@
#include "swrenderer/drawers/r_draw_pal.h"
#include "swrenderer/viewport/r_viewport.h"
#include "r_memory.h"
#include "common/rendering/polyrenderer/drawers/poly_thread.h"
std::pair<PalEntry, PalEntry>& R_GetSkyCapColor(FGameTexture* tex);
@ -75,7 +74,6 @@ namespace swrenderer
PlaneList.reset(new VisiblePlaneList(this));
DrawSegments.reset(new DrawSegmentList(this));
ClipSegments.reset(new RenderClipSegment());
Poly.reset(new PolyTriangleThreadData(0, 1, 0, 1, 0, screen->GetHeight()));
tc_drawers.reset(new SWTruecolorDrawers(this));
pal_drawers.reset(new SWPalDrawers(this));
}

View file

@ -26,11 +26,9 @@
#include <thread>
class RenderMemory;
class PolyTriangleThreadData;
struct FDynamicLight;
EXTERN_CVAR(Bool, r_models);
extern bool r_modelscene;
namespace swrenderer
{
@ -75,7 +73,6 @@ namespace swrenderer
std::unique_ptr<RenderClipSegment> ClipSegments;
std::unique_ptr<RenderViewport> Viewport;
std::unique_ptr<LightVisibility> Light;
std::unique_ptr<PolyTriangleThreadData> Poly;
TArray<FDynamicLight*> AddedLightsArray;

View file

@ -46,7 +46,6 @@
#include "swrenderer/things/r_wallsprite.h"
#include "swrenderer/things/r_voxel.h"
#include "swrenderer/things/r_particle.h"
#include "swrenderer/things/r_model.h"
#include "swrenderer/segments/r_clipsegment.h"
#include "swrenderer/line/r_wallsetup.h"
#include "swrenderer/line/r_farclip_line.h"
@ -932,13 +931,7 @@ namespace swrenderer
ThingSprite sprite;
int spritenum = thing->sprite;
bool isPicnumOverride = thing->picnum.isValid();
FSpriteModelFrame *modelframe = isPicnumOverride ? nullptr : FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED));
if (r_modelscene && modelframe && (thing->Pos() - Thread->Viewport->viewpoint.Pos).LengthSquared() < model_distance_cull)
{
DVector3 pos = thing->InterpolatedPosition(Thread->Viewport->viewpoint.TicFrac);
RenderModel::Project(Thread, (float)pos.X, (float)pos.Y, (float)pos.Z, modelframe, thing);
}
else if (GetThingSprite(thing, sprite))
if (GetThingSprite(thing, sprite))
{
int thinglightlevel;
if (sec->sectornum != thing->Sector->sectornum) // compare sectornums to account for R_FakeFlat copies.

View file

@ -65,8 +65,6 @@ EXTERN_CVAR(Int, r_debug_draw)
CVAR(Int, r_scene_multithreaded, 1, 0);
CVAR(Bool, r_models, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
bool r_modelscene = false;
namespace swrenderer
{
cycle_t WallCycles, PlaneCycles, MaskedCycles;
@ -100,18 +98,6 @@ namespace swrenderer
ActiveRatio(width, height, &trueratio);
viewport->SetViewport(player->camera->Level, MainThread(), width, height, trueratio);
/*r_modelscene = r_models && Models.Size() > 0;
if (r_modelscene)
{
if (!DepthStencil || DepthStencil->Width() != viewport->RenderTarget->GetWidth() || DepthStencil->Height() != viewport->RenderTarget->GetHeight())
{
DepthStencil.reset();
DepthStencil.reset(new PolyDepthStencil(viewport->RenderTarget->GetWidth(), viewport->RenderTarget->GetHeight()));
}
PolyTriangleDrawer::SetViewport(MainThread()->DrawQueue, 0, 0, viewport->RenderTarget->GetWidth(), viewport->RenderTarget->GetHeight(), viewport->RenderTarget, DepthStencil.get());
PolyTriangleDrawer::ClearStencil(MainThread()->DrawQueue, 0);
}*/
if (r_clearbuffer != 0 || r_debug_draw != 0)
{
if (!viewport->RenderTarget->IsBgra())
@ -158,9 +144,6 @@ namespace swrenderer
R_UpdateFuzzPosFrameStart();
if (r_modelscene)
MainThread()->Viewport->SetupPolyViewport(MainThread());
FRenderViewpoint origviewpoint = MainThread()->Viewport->viewpoint;
ActorRenderFlags savedflags = MainThread()->Viewport->viewpoint.camera->renderflags;
@ -174,8 +157,6 @@ namespace swrenderer
// Mirrors fail to restore the original viewpoint -- we need it for the HUD weapon to draw correctly.
MainThread()->Viewport->viewpoint = origviewpoint;
if (r_modelscene)
MainThread()->Viewport->SetupPolyViewport(MainThread());
if (renderPlayerSprites)
RenderPSprites();
@ -259,12 +240,6 @@ namespace swrenderer
thread->OpaquePass->ResetFakingUnderwater(); // [RH] Hack to make windows into underwater areas possible
thread->Portal->SetMainPortal();
/*if (r_modelscene && thread->MainThread)
PolyTriangleDrawer::ClearStencil(MainThread()->DrawQueue, 0);
PolyTriangleDrawer::SetViewport(thread->DrawQueue, viewwindowx, viewwindowy, viewwidth, viewheight, thread->Viewport->RenderTarget, DepthStencil.get());
PolyTriangleDrawer::SetScissor(thread->DrawQueue, viewwindowx, viewwindowy, viewwidth, viewheight);*/
// Cull things outside the range seen by this thread
VisibleSegmentRenderer visitor;
if (thread->X1 > 0)
@ -388,14 +363,6 @@ namespace swrenderer
viewwindowy = y;
viewactive = true;
viewport->SetViewport(actor->Level, MainThread(), width, height, MainThread()->Viewport->viewwindow.WidescreenRatio);
if (r_modelscene)
{
if (!DepthStencil || DepthStencil->Width() != viewport->RenderTarget->GetWidth() || DepthStencil->Height() != viewport->RenderTarget->GetHeight())
{
DepthStencil.reset();
DepthStencil.reset(new PolyDepthStencil(viewport->RenderTarget->GetWidth(), viewport->RenderTarget->GetHeight()));
}
}
// Render:
RenderActorView(actor, false, dontmaplines);

View file

@ -32,8 +32,6 @@
extern cycle_t FrameCycles;
class PolyDepthStencil;
namespace swrenderer
{
extern cycle_t WallCycles, PlaneCycles, MaskedCycles, DrawerWaitCycles;
@ -69,7 +67,6 @@ namespace swrenderer
bool dontmaplines = false;
int clearcolor = 0;
std::unique_ptr<PolyDepthStencil> DepthStencil;
std::vector<std::unique_ptr<RenderThread>> Threads;
std::mutex start_mutex;
std::condition_variable start_condition;

View file

@ -1,443 +0,0 @@
/*
** Polygon Doom software renderer
** Copyright (c) 2016 Magnus Norddahl
**
** This software is provided 'as-is', without any express or implied
** warranty. In no event will the authors be held liable for any damages
** arising from the use of this software.
**
** Permission is granted to anyone to use this software for any purpose,
** including commercial applications, and to alter it and redistribute it
** freely, subject to the following restrictions:
**
** 1. The origin of this software must not be misrepresented; you must not
** claim that you wrote the original software. If you use this software
** in a product, an acknowledgment in the product documentation would be
** appreciated but is not required.
** 2. Altered source versions must be plainly marked as such, and must not be
** misrepresented as being the original software.
** 3. This notice may not be removed or altered from any source distribution.
**
*/
#include <stdlib.h>
#include "doomdef.h"
#include "sbar.h"
#include "r_data/r_translate.h"
#include "r_model.h"
#include "r_data/r_vanillatrans.h"
#include "actorinlines.h"
#include "i_time.h"
#include "texturemanager.h"
#include "r_memory.h"
#include "swrenderer/r_swcolormaps.h"
#include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/scene/r_light.h"
namespace swrenderer
{
void RenderModel::Project(RenderThread *thread, float x, float y, float z, FSpriteModelFrame *smf, AActor *actor)
{
// transform the origin point
double tr_x = x - thread->Viewport->viewpoint.Pos.X;
double tr_y = y - thread->Viewport->viewpoint.Pos.Y;
double tz = tr_x * thread->Viewport->viewpoint.TanCos + tr_y * thread->Viewport->viewpoint.TanSin;
// thing is behind view plane?
if (tz < MINZ)
return;
double tx = tr_x * thread->Viewport->viewpoint.Sin - tr_y * thread->Viewport->viewpoint.Cos;
// Flip for mirrors
if (thread->Portal->MirrorFlags & RF_XFLIP)
{
tx = viewwidth - tx - 1;
}
// too far off the side?
if (fabs(tx / 64) > fabs(tz))
return;
RenderModel *vis = thread->FrameMemory->NewObject<RenderModel>(x, y, z, smf, actor, float(1 / tz));
vis->CurrentPortalUniq = thread->Portal->CurrentPortalUniq;
vis->WorldToClip = thread->Viewport->WorldToClip;
vis->MirrorWorldToClip = !!(thread->Portal->MirrorFlags & RF_XFLIP);
thread->SpriteList->Push(vis);
}
RenderModel::RenderModel(float x, float y, float z, FSpriteModelFrame *smf, AActor *actor, float idepth) : x(x), y(y), z(z), smf(smf), actor(actor)
{
gpos = { x, y, z };
this->idepth = idepth;
}
void RenderModel::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor)
{
#if 0
SWModelRenderer renderer(thread, clip3DFloor, &WorldToClip, MirrorWorldToClip);
renderer.sector = actor->Sector;
renderer.RenderStyle = actor->RenderStyle;
renderer.RenderAlpha = (float)actor->Alpha;
if (!renderer.RenderStyle.IsVisible(renderer.RenderAlpha))
return;
bool foggy = false;
int actualextralight = foggy ? 0 : thread->Viewport->viewpoint.extralight << 4;
bool fullbrightSprite = ((actor->renderflags & RF_FULLBRIGHT) || (actor->flags5 & MF5_BRIGHT));
renderer.lightlevel = fullbrightSprite ? 255 : actor->Sector->lightlevel + actualextralight;
renderer.visibility = thread->Light->SpriteGlobVis(foggy);
renderer.fillcolor = actor->fillcolor;
renderer.Translation = actor->Translation;
renderer.AddLights(actor);
RenderModel(&renderer, x, y, z, smf, actor, r_viewpoint.TicFrac);
PolyTriangleDrawer::SetModelVertexShader(thread->DrawQueue, -1, -1, 0.0f);
#endif
}
/////////////////////////////////////////////////////////////////////////////
static bool isBright(DPSprite *psp)
{
if (psp != nullptr && psp->GetState() != nullptr)
{
bool disablefullbright = false;
FTextureID lump = sprites[psp->GetSprite()].GetSpriteFrame(psp->GetFrame(), 0, 0., nullptr);
if (lump.isValid())
{
auto tex = TexMan.GetGameTexture(lump, true);
if (tex) disablefullbright = tex->isFullbrightDisabled();
}
return psp->GetState()->GetFullbright() && !disablefullbright;
}
return false;
}
void RenderHUDModel(RenderThread *thread, DPSprite *psp, float ofsx, float ofsy)
{
#if 0
SWModelRenderer renderer(thread, Fake3DTranslucent(), &thread->Viewport->WorldToClip, false);
AActor *playermo = players[consoleplayer].camera;
auto rs = psp->GetRenderStyle(playermo->RenderStyle, playermo->Alpha);
renderer.sector = playermo->Sector;
renderer.RenderStyle = rs.first;
renderer.RenderAlpha = rs.second;
if (psp->Flags & PSPF_FORCEALPHA) renderer.RenderAlpha = 0.0f;
if (!renderer.RenderStyle.IsVisible(renderer.RenderAlpha))
return;
bool foggy = false;
int actualextralight = foggy ? 0 : thread->Viewport->viewpoint.extralight << 4;
bool fullbrightSprite = isBright(psp);
renderer.lightlevel = fullbrightSprite ? 255 : playermo->Sector->lightlevel + actualextralight;
renderer.visibility = thread->Light->SpriteGlobVis(foggy);
PalEntry ThingColor = (playermo->RenderStyle.Flags & STYLEF_ColorIsFixed) ? playermo->fillcolor : 0xffffff;
ThingColor.a = 255;
renderer.fillcolor = fullbrightSprite ? ThingColor : ThingColor.Modulate(playermo->Sector->SpecialColors[sector_t::sprites]);
uint32_t trans = psp->GetTranslation() != 0 ? psp->GetTranslation() : 0;
if ((psp->Flags & PSPF_PLAYERTRANSLATED)) trans = playermo->Translation;
renderer.Translation = trans;
RenderHUDModel(&renderer, psp, ofsx, ofsy);
PolyTriangleDrawer::SetModelVertexShader(thread->DrawQueue, -1, -1, 0.0f);
#endif
}
/////////////////////////////////////////////////////////////////////////////
#if 0
SWModelRenderer::SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor, Mat4f *worldToClip, bool mirrorWorldToClip)
: Thread(thread), Clip3DFloor(clip3DFloor), WorldToClip(worldToClip), MirrorWorldToClip(mirrorWorldToClip)
{
static PolySWInputAssembly input;
PolyTriangleDrawer::SetInputAssembly(thread->DrawQueue, &input);
}
void SWModelRenderer::AddLights(AActor *actor)
{
if (r_dynlights && actor)
{
auto &addedLights = Thread->AddedLightsArray;
addedLights.Clear();
float x = (float)actor->X();
float y = (float)actor->Y();
float z = (float)actor->Center();
float actorradius = (float)actor->RenderRadius();
float radiusSquared = actorradius * actorradius;
BSPWalkCircle(actor->Level, x, y, radiusSquared, [&](subsector_t *subsector) // Iterate through all subsectors potentially touched by actor
{
FLightNode * node = subsector->section->lighthead;
while (node) // check all lights touching a subsector
{
FDynamicLight *light = node->lightsource;
if (light->ShouldLightActor(actor))
{
int group = subsector->sector->PortalGroup;
DVector3 pos = light->PosRelative(group);
float radius = (float)(light->GetRadius() + actorradius);
double dx = pos.X - x;
double dy = pos.Y - y;
double dz = pos.Z - z;
double distSquared = dx * dx + dy * dy + dz * dz;
if (distSquared < radius * radius) // Light and actor touches
{
if (std::find(addedLights.begin(), addedLights.end(), light) == addedLights.end()) // Check if we already added this light from a different subsector
{
addedLights.Push(light);
}
}
}
node = node->nextLight;
}
});
NumLights = addedLights.Size();
Lights = Thread->FrameMemory->AllocMemory<PolyLight>(NumLights);
for (int i = 0; i < NumLights; i++)
{
FDynamicLight *lightsource = addedLights[i];
bool is_point_light = lightsource->IsAttenuated();
uint32_t red = lightsource->GetRed();
uint32_t green = lightsource->GetGreen();
uint32_t blue = lightsource->GetBlue();
PolyLight &light = Lights[i];
light.x = (float)lightsource->X();
light.y = (float)lightsource->Y();
light.z = (float)lightsource->Z();
light.radius = 256.0f / lightsource->GetRadius();
light.color = (red << 16) | (green << 8) | blue;
if (is_point_light)
light.radius = -light.radius;
}
}
}
void SWModelRenderer::BeginDrawModel(FRenderStyale style, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored)
{
const_cast<VSMatrix &>(objectToWorldMatrix).copy(ObjectToWorld.Matrix);
ClipTop = {};
ClipBottom = {};
if (Clip3DFloor.clipTop || Clip3DFloor.clipBottom)
{
// Convert 3d floor clipping planes from world to object space
VSMatrix inverseMat;
const_cast<VSMatrix &>(objectToWorldMatrix).inverseMatrix(inverseMat);
Mat4f worldToObject;
inverseMat.copy(worldToObject.Matrix);
// Note: Y and Z is swapped here
Vec4f one = worldToObject * Vec4f(0.0f, 1.0f, 0.0f, 1.0f);
Vec4f zero = worldToObject * Vec4f(0.0f, 0.0f, 0.0f, 1.0f);
Vec4f up = { one.X - zero.X, one.Y - zero.Y, one.Z - zero.Z };
if (Clip3DFloor.clipTop)
{
Vec4f p = worldToObject * Vec4f(0.0f, Clip3DFloor.sclipTop, 0.0f, 1.0f);
float d = up.X * p.X + up.Y * p.Y + up.Z * p.Z;
ClipTop = { -up.X, -up.Y, -up.Z, d };
}
if (Clip3DFloor.clipBottom)
{
Vec4f p = worldToObject * Vec4f(0.0f, Clip3DFloor.sclipBottom, 0.0f, 1.0f);
float d = up.X * p.X + up.Y * p.Y + up.Z * p.Z;
ClipBottom = { up.X, up.Y, up.Z, -d };
}
}
SetTransform();
if (style == LegacyRenderStyles[STYLE_Normal] || !!(smf->flags & MDL_DONTCULLBACKFACES))
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true);
PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, !(mirrored ^ MirrorWorldToClip));
}
void SWModelRenderer::EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf)
{
if (style == LegacyRenderStyles[STYLE_Normal] || !!(smf->flags & MDL_DONTCULLBACKFACES))
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false);
PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, true);
}
IModelVertexBuffer *SWModelRenderer::CreateVertexBuffer(bool needindex, bool singleframe)
{
return new SWModelVertexBuffer(needindex, singleframe);
}
VSMatrix SWModelRenderer::GetViewToWorldMatrix()
{
// Calculate the WorldToView matrix as it would have looked like without yshearing:
const auto &Viewpoint = Thread->Viewport->viewpoint;
auto Level = Thread->Viewport->Level();
const auto &Viewwindow = Thread->Viewport->viewwindow;
double radPitch = Viewpoint.Angles.Pitch.Normalized180().Radians();
double angx = cos(radPitch);
double angy = sin(radPitch) * Level->info->pixelstretch;
double alen = sqrt(angx*angx + angy*angy);
float adjustedPitch = (float)asin(angy / alen);
float adjustedViewAngle = (float)(Viewpoint.Angles.Yaw - 90).Radians();
float ratio = Viewwindow.WidescreenRatio;
float fovratio = (Viewwindow.WidescreenRatio >= 1.3f) ? 1.333333f : ratio;
float fovy = (float)(2 * DAngle::ToDegrees(atan(tan(Viewpoint.FieldOfView.Radians() / 2) / fovratio)).Degrees);
Mat4f altWorldToView =
Mat4f::Rotate(adjustedPitch, 1.0f, 0.0f, 0.0f) *
Mat4f::Rotate(adjustedViewAngle, 0.0f, -1.0f, 0.0f) *
Mat4f::Scale(1.0f, Level->info->pixelstretch, 1.0f) *
Mat4f::SwapYZ() *
Mat4f::Translate((float)-Viewpoint.Pos.X, (float)-Viewpoint.Pos.Y, (float)-Viewpoint.Pos.Z);
Mat4f swapYZ = Mat4f::Null();
swapYZ.Matrix[0 + 0 * 4] = 1.0f;
swapYZ.Matrix[1 + 2 * 4] = 1.0f;
swapYZ.Matrix[2 + 1 * 4] = 1.0f;
swapYZ.Matrix[3 + 3 * 4] = 1.0f;
VSMatrix worldToView;
worldToView.loadMatrix((altWorldToView * swapYZ).Matrix);
VSMatrix objectToWorld;
worldToView.inverseMatrix(objectToWorld);
return objectToWorld;
}
void SWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored)
{
const_cast<VSMatrix &>(objectToWorldMatrix).copy(ObjectToWorld.Matrix);
ClipTop = {};
ClipBottom = {};
SetTransform();
PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, true);
if (style == LegacyRenderStyles[STYLE_Normal])
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true);
PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, !(mirrored ^ MirrorWorldToClip));
}
void SWModelRenderer::EndDrawHUDModel(FRenderStyle style)
{
PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, false);
if (style == LegacyRenderStyles[STYLE_Normal])
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false);
PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, true);
}
void SWModelRenderer::SetInterpolation(double interpolation)
{
InterpolationFactor = (float)interpolation;
}
void SWModelRenderer::SetMaterial(FTexture *skin, bool clampNoFilter, int translation)
{
SkinTexture = skin;
}
void SWModelRenderer::SetTransform()
{
Mat4f swapYZ = Mat4f::Null();
swapYZ.Matrix[0 + 0 * 4] = 1.0f;
swapYZ.Matrix[1 + 2 * 4] = 1.0f;
swapYZ.Matrix[2 + 1 * 4] = 1.0f;
swapYZ.Matrix[3 + 3 * 4] = 1.0f;
ObjectToWorld = swapYZ * ObjectToWorld;
PolyTriangleDrawer::SetTransform(Thread->DrawQueue, Thread->FrameMemory->NewObject<Mat4f>((*WorldToClip) * ObjectToWorld), Thread->FrameMemory->NewObject<Mat4f>(ObjectToWorld));
}
void SWModelRenderer::DrawArrays(int start, int count)
{
PolyDrawArgs args;
auto nc = !!(sector->Level->flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING);
args.SetLight(GetSpriteColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], nc), lightlevel, visibility, fullbrightSprite);
args.SetLights(Lights, NumLights);
args.SetNormal(FVector3(0.0f, 0.0f, 0.0f));
args.SetStyle(RenderStyle, RenderAlpha, fillcolor, Translation, SkinTexture->GetSoftwareTexture(), fullbrightSprite);
args.SetDepthTest(true);
args.SetWriteDepth(true);
args.SetWriteStencil(false);
args.SetClipPlane(0, PolyClipPlane());
args.SetClipPlane(1, ClipTop);
args.SetClipPlane(2, ClipBottom);
PolyTriangleDrawer::PushDrawArgs(Thread->DrawQueue, args);
PolyTriangleDrawer::Draw(Thread->DrawQueue, start, count);
}
void SWModelRenderer::DrawElements(int numIndices, size_t offset)
{
PolyDrawArgs args;
auto nc = !!(sector->Level->flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING);
args.SetLight(GetSpriteColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], nc), lightlevel, visibility, fullbrightSprite);
args.SetLights(Lights, NumLights);
args.SetNormal(FVector3(0.0f, 0.0f, 0.0f));
args.SetStyle(RenderStyle, RenderAlpha, fillcolor, Translation, SkinTexture->GetSoftwareTexture(), fullbrightSprite);
args.SetDepthTest(true);
args.SetWriteDepth(true);
args.SetWriteStencil(false);
args.SetClipPlane(0, PolyClipPlane());
args.SetClipPlane(1, ClipTop);
args.SetClipPlane(2, ClipBottom);
PolyTriangleDrawer::PushDrawArgs(Thread->DrawQueue, args);
PolyTriangleDrawer::DrawIndexed(Thread->DrawQueue, static_cast<int>(offset / sizeof(unsigned int)), numIndices);
}
/////////////////////////////////////////////////////////////////////////////
SWModelVertexBuffer::SWModelVertexBuffer(bool needindex, bool singleframe)
{
}
SWModelVertexBuffer::~SWModelVertexBuffer()
{
}
FModelVertex *SWModelVertexBuffer::LockVertexBuffer(unsigned int size)
{
mVertexBuffer.Resize(size);
return &mVertexBuffer[0];
}
void SWModelVertexBuffer::UnlockVertexBuffer()
{
}
unsigned int *SWModelVertexBuffer::LockIndexBuffer(unsigned int size)
{
mIndexBuffer.Resize(size);
return &mIndexBuffer[0];
}
void SWModelVertexBuffer::UnlockIndexBuffer()
{
}
void SWModelVertexBuffer::SetupFrame(FModelRenderer *renderer, unsigned int frame1, unsigned int frame2, unsigned int size)
{
SWModelRenderer *swrenderer = (SWModelRenderer *)renderer;
if (mVertexBuffer.Size() > 0)
PolyTriangleDrawer::SetVertexBuffer(swrenderer->Thread->DrawQueue, &mVertexBuffer[0]);
if (mIndexBuffer.Size() > 0)
PolyTriangleDrawer::SetIndexBuffer(swrenderer->Thread->DrawQueue, &mIndexBuffer[0]);
PolyTriangleDrawer::SetModelVertexShader(swrenderer->Thread->DrawQueue, frame1, frame2, swrenderer->InterpolationFactor);
}
#endif
}

View file

@ -1,120 +0,0 @@
/*
** Polygon Doom software renderer
** Copyright (c) 2016 Magnus Norddahl
**
** This software is provided 'as-is', without any express or implied
** warranty. In no event will the authors be held liable for any damages
** arising from the use of this software.
**
** Permission is granted to anyone to use this software for any purpose,
** including commercial applications, and to alter it and redistribute it
** freely, subject to the following restrictions:
**
** 1. The origin of this software must not be misrepresented; you must not
** claim that you wrote the original software. If you use this software
** in a product, an acknowledgment in the product documentation would be
** appreciated but is not required.
** 2. Altered source versions must be plainly marked as such, and must not be
** misrepresented as being the original software.
** 3. This notice may not be removed or altered from any source distribution.
**
*/
#pragma once
#include "polyrenderer/drawers/poly_triangle.h"
#include "matrix.h"
#include "models.h"
#include "swrenderer/r_renderthread.h"
#include "swrenderer/things/r_visiblesprite.h"
struct PolyLight;
namespace swrenderer
{
void RenderHUDModel(RenderThread *thread, DPSprite *psp, float ofsx, float ofsy);
class RenderModel : public VisibleSprite
{
public:
RenderModel(float x, float y, float z, FSpriteModelFrame *smf, AActor *actor, float idepth);
static void Project(RenderThread *thread, float x, float y, float z, FSpriteModelFrame *smf, AActor *actor);
protected:
void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) override;
bool IsModel() const override { return true; }
private:
float x, y, z;
FSpriteModelFrame *smf;
AActor *actor;
VSMatrix WorldToClip;
bool MirrorWorldToClip;
};
#if 0
class SWModelRenderer : public FModelRenderer
{
public:
SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor, Mat4f *worldToClip, bool mirrorWorldToClip);
void AddLights(AActor *actor);
ModelRendererType GetType() const override { return SWModelRendererType; }
void BeginDrawModel(FRenderStyle style, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored) override;
void EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf) override;
IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) override;
VSMatrix GetViewToWorldMatrix() override;
void BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored) override;
void EndDrawHUDModel(FRenderStyle style) override;
void SetInterpolation(double interpolation) override;
void SetMaterial(FTexture *skin, bool clampNoFilter, int translation) override;
void DrawArrays(int start, int count) override;
void DrawElements(int numIndices, size_t offset) override;
void SetTransform();
RenderThread *Thread = nullptr;
Fake3DTranslucent Clip3DFloor;
FRenderStyle RenderStyle;
float RenderAlpha;
sector_t *sector;
bool fullbrightSprite;
int lightlevel;
double visibility;
uint32_t fillcolor;
uint32_t Translation;
Mat4f ObjectToWorld;
PolyClipPlane ClipTop, ClipBottom;
FTexture *SkinTexture = nullptr;
float InterpolationFactor = 0.0;
Mat4f *WorldToClip = nullptr;
bool MirrorWorldToClip = false;
PolyLight *Lights = nullptr;
int NumLights = 0;
};
class SWModelVertexBuffer : public IModelVertexBuffer
{
public:
SWModelVertexBuffer(bool needindex, bool singleframe);
~SWModelVertexBuffer();
FModelVertex *LockVertexBuffer(unsigned int size) override;
void UnlockVertexBuffer() override;
unsigned int *LockIndexBuffer(unsigned int size) override;
void UnlockIndexBuffer() override;
void SetupFrame(FModelRenderer *renderer, unsigned int frame1, unsigned int frame2, unsigned int size) override;
private:
TArray<FModelVertex> mVertexBuffer;
TArray<unsigned int> mIndexBuffer;
};
#endif
}

View file

@ -97,8 +97,6 @@ namespace swrenderer
(r_deathcamera && Thread->Viewport->viewpoint.camera->health <= 0))
return;
renderHUDModel = r_modelscene && IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player);
FDynamicColormap *basecolormap;
CameraLight *cameraLight = CameraLight::Instance();
auto nc = !!(Thread->Viewport->Level()->flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING);
@ -256,12 +254,6 @@ namespace swrenderer
sy += wy;
}
if (renderHUDModel)
{
RenderHUDModel(Thread, pspr, (float)sx, (float)sy);
return;
}
auto viewport = Thread->Viewport.get();
double pspritexscale = viewport->viewwindow.centerxwide / 160.0;

View file

@ -97,6 +97,5 @@ namespace swrenderer
TArray<HWAccelPlayerSprite> AcceleratedSprites;
sector_t tempsec;
bool renderHUDModel = false;
};
}

View file

@ -316,24 +316,6 @@ namespace swrenderer
DrawSegmentList *segmentlist = thread->DrawSegments.get();
RenderPortal *renderportal = thread->Portal.get();
// Render draw segments behind sprite
if (r_modelscene)
{
int subsectordepth = spr->SubsectorDepth;
for (unsigned int index = 0; index != segmentlist->TranslucentSegmentsCount(); index++)
{
DrawSegment *ds = segmentlist->TranslucentSegment(index);
if (ds->drawsegclip.SubsectorDepth >= subsectordepth && ds->drawsegclip.CurrentPortalUniq == renderportal->CurrentPortalUniq)
{
int r1 = max<int>(ds->x1, 0);
int r2 = min<int>(ds->x2, viewwidth - 1);
RenderDrawSegment renderer(thread);
renderer.Render(ds, r1, r2, clip3DFloor);
}
}
}
else
{
for (unsigned int index = 0; index != segmentlist->TranslucentSegmentsCount(); index++)
{

View file

@ -83,23 +83,6 @@ namespace swrenderer
SortedSprites[i] = Sprites[first + count - i - 1];
}
if (r_modelscene)
{
for (unsigned int i = 0; i < count; i++)
{
FVector2 worldPos = SortedSprites[i]->WorldPos().XY();
SortedSprites[i]->SubsectorDepth = FindSubsectorDepth(thread, { worldPos.X, worldPos.Y });
}
std::stable_sort(&SortedSprites[0], &SortedSprites[count], [](VisibleSprite *a, VisibleSprite *b) -> bool
{
if (a->SubsectorDepth != b->SubsectorDepth)
return a->SubsectorDepth < b->SubsectorDepth;
else
return a->SortDist() > b->SortDist();
});
}
else
{
std::stable_sort(&SortedSprites[0], &SortedSprites[count], [](VisibleSprite *a, VisibleSprite *b) -> bool
{

View file

@ -25,11 +25,6 @@
namespace swrenderer
{
void SkyDrawerArgs::DrawDepthSkyColumn(RenderThread *thread, float idepth)
{
thread->Drawers(dc_viewport)->DrawDepthSkyColumn(*this, idepth);
}
void SkyDrawerArgs::DrawSingleSkyColumn(RenderThread *thread)
{
thread->Drawers(dc_viewport)->DrawSingleSkyColumn(*this);

View file

@ -121,11 +121,6 @@ namespace swrenderer
}
}
void SpanDrawerArgs::DrawDepthSpan(RenderThread *thread, float idepth1, float idepth2)
{
thread->Drawers(ds_viewport)->DrawDepthSpan(*this, idepth1, idepth2);
}
void SpanDrawerArgs::DrawSpan(RenderThread *thread)
{
(thread->Drawers(ds_viewport)->*spanfunc)(*this);

View file

@ -11,8 +11,6 @@
#define MINZ double((2048*4) / double(1 << 20))
class PolyDepthStencil;
namespace swrenderer
{
class RenderThread;