From bce49ad7c8a52fd75f79d5532fabe855e31d7307 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 17 Jun 2018 14:56:34 +0200 Subject: [PATCH] - fix Software models don't display over nonexistent sprites --- src/polyrenderer/scene/poly_scene.cpp | 56 +++++++++++++++++++++++--- src/polyrenderer/scene/poly_scene.h | 1 + src/polyrenderer/scene/poly_sprite.cpp | 9 ++--- src/swrenderer/scene/r_opaque_pass.cpp | 30 ++++++-------- 4 files changed, 68 insertions(+), 28 deletions(-) diff --git a/src/polyrenderer/scene/poly_scene.cpp b/src/polyrenderer/scene/poly_scene.cpp index 469f56bc9..284f24b1a 100644 --- a/src/polyrenderer/scene/poly_scene.cpp +++ b/src/polyrenderer/scene/poly_scene.cpp @@ -37,6 +37,8 @@ EXTERN_CVAR(Int, r_portal_recursions) +extern double model_distance_cull; + ///////////////////////////////////////////////////////////////////////////// RenderPolyScene::RenderPolyScene() @@ -71,11 +73,24 @@ void RenderPolyScene::Render(PolyPortalViewpoint *viewpoint) sector_t *sector = &level.sectors[sectorIndex]; for (AActor *thing = sector->thinglist; thing != nullptr; thing = thing->snext) { - DVector2 left, right; - if (!RenderPolySprite::GetLine(thing, left, right)) - continue; - double distanceSquared = (thing->Pos() - rviewpoint.Pos).LengthSquared(); - AddSprite(thread, thing, distanceSquared, left, right); + if (!RenderPolySprite::IsThingCulled(thing)) + { + int spritenum = thing->sprite; + bool isPicnumOverride = thing->picnum.isValid(); + FSpriteModelFrame *modelframe = isPicnumOverride ? nullptr : FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED)); + double distanceSquared = (thing->Pos() - rviewpoint.Pos).LengthSquared(); + if (r_modelscene && modelframe && distanceSquared < model_distance_cull) + { + AddModel(thread, thing, distanceSquared, thing->Pos()); + } + else + { + DVector2 left, right; + if (!RenderPolySprite::GetLine(thing, left, right)) + continue; + AddSprite(thread, thing, distanceSquared, left, right); + } + } } } PolyMaskedCycles.Unclock(); @@ -296,6 +311,37 @@ void RenderPolyScene::AddSprite(PolyRenderThread *thread, AActor *thing, double thread->TranslucentObjects.push_back(thread->FrameMemory->NewObject(thing, sub, Cull.SubsectorDepths[sub->Index()], sortDistance, (float)t1, (float)t2, CurrentViewpoint->StencilValue)); } +void RenderPolyScene::AddModel(PolyRenderThread *thread, AActor *thing, double sortDistance, DVector2 pos) +{ + if (level.nodes.Size() == 0) + { + subsector_t *sub = &level.subsectors[0]; + if (Cull.SubsectorDepths[sub->Index()] != 0xffffffff) + thread->TranslucentObjects.push_back(thread->FrameMemory->NewObject(thing, sub, Cull.SubsectorDepths[sub->Index()], sortDistance, 0.0f, 1.0f, CurrentViewpoint->StencilValue)); + } + else + { + void *node = level.HeadNode(); + + while (!((size_t)node & 1)) // Keep going until found a subsector + { + node_t *bsp = (node_t *)node; + + DVector2 planePos(FIXED2DBL(bsp->x), FIXED2DBL(bsp->y)); + DVector2 planeNormal = DVector2(FIXED2DBL(-bsp->dy), FIXED2DBL(bsp->dx)); + double planeD = planeNormal | planePos; + + int side = (pos | planeNormal) > planeD; + node = bsp->children[side]; + } + + subsector_t *sub = (subsector_t *)((uint8_t *)node - 1); + + if (Cull.SubsectorDepths[sub->Index()] != 0xffffffff) + thread->TranslucentObjects.push_back(thread->FrameMemory->NewObject(thing, sub, Cull.SubsectorDepths[sub->Index()], sortDistance, 0.0f, 1.0f, CurrentViewpoint->StencilValue)); + } +} + void RenderPolyScene::RenderLine(PolyRenderThread *thread, subsector_t *sub, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth) { // Tell automap we saw this diff --git a/src/polyrenderer/scene/poly_scene.h b/src/polyrenderer/scene/poly_scene.h index 26241a027..238116c52 100644 --- a/src/polyrenderer/scene/poly_scene.h +++ b/src/polyrenderer/scene/poly_scene.h @@ -96,6 +96,7 @@ private: void RenderLine(PolyRenderThread *thread, subsector_t *sub, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth); void AddSprite(PolyRenderThread *thread, AActor *thing, double sortDistance, const DVector2 &left, const DVector2 &right); void AddSprite(PolyRenderThread *thread, AActor *thing, double sortDistance, DVector2 left, DVector2 right, double t1, double t2, void *node); + void AddModel(PolyRenderThread *thread, AActor *thing, double sortDistance, DVector2 pos); void RenderPolySubsector(PolyRenderThread *thread, subsector_t *sub, uint32_t subsectorDepth, sector_t *frontsector); void RenderPolyNode(PolyRenderThread *thread, void *node, uint32_t subsectorDepth, sector_t *frontsector); diff --git a/src/polyrenderer/scene/poly_sprite.cpp b/src/polyrenderer/scene/poly_sprite.cpp index 7be5648b0..3b1b4347b 100644 --- a/src/polyrenderer/scene/poly_sprite.cpp +++ b/src/polyrenderer/scene/poly_sprite.cpp @@ -39,13 +39,12 @@ EXTERN_CVAR (Bool, r_debug_disable_vis_filter) EXTERN_CVAR(Int, gl_spriteclip) EXTERN_CVAR(Float, gl_sclipthreshold) EXTERN_CVAR(Float, gl_sclipfactor) + extern uint32_t r_renderercaps; +extern double model_distance_cull; bool RenderPolySprite::GetLine(AActor *thing, DVector2 &left, DVector2 &right) { - if (IsThingCulled(thing)) - return false; - const auto &viewpoint = PolyRenderer::Instance()->Viewpoint; DVector3 pos = thing->InterpolatedPosition(viewpoint.TicFrac); @@ -76,12 +75,12 @@ void RenderPolySprite::Render(PolyRenderThread *thread, AActor *thing, subsector { if (r_modelscene) { + const auto &viewpoint = PolyRenderer::Instance()->Viewpoint; int spritenum = thing->sprite; bool isPicnumOverride = thing->picnum.isValid(); FSpriteModelFrame *modelframe = isPicnumOverride ? nullptr : FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED)); - if (modelframe) + if (modelframe && (thing->Pos() - viewpoint.Pos).LengthSquared() < model_distance_cull) { - const auto &viewpoint = PolyRenderer::Instance()->Viewpoint; DVector3 pos = thing->InterpolatedPosition(viewpoint.TicFrac); PolyRenderModel(thread, PolyRenderer::Instance()->Scene.CurrentViewpoint->WorldToClip, stencilValue, (float)pos.X, (float)pos.Y, (float)pos.Z, modelframe, thing); return; diff --git a/src/swrenderer/scene/r_opaque_pass.cpp b/src/swrenderer/scene/r_opaque_pass.cpp index 1cb7045eb..987b89b5b 100644 --- a/src/swrenderer/scene/r_opaque_pass.cpp +++ b/src/swrenderer/scene/r_opaque_pass.cpp @@ -76,11 +76,12 @@ EXTERN_CVAR(Bool, r_drawvoxels); EXTERN_CVAR(Bool, r_debug_disable_vis_filter); extern uint32_t r_renderercaps; +double model_distance_cull = 1e16; + namespace { double sprite_distance_cull = 1e16; double line_distance_cull = 1e16; - double model_distance_cull = 1e16; } CUSTOM_CVAR(Float, r_sprite_distance_cull, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) @@ -935,7 +936,15 @@ namespace swrenderer if (IsPotentiallyVisible(thing)) { ThingSprite sprite; - if (GetThingSprite(thing, 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)) { FDynamicColormap *thingColormap = basecolormap; int thingShade = spriteshade; @@ -954,24 +963,9 @@ namespace swrenderer { RenderVoxel::Project(Thread, thing, sprite.pos, sprite.voxel, sprite.spriteScale, sprite.renderflags, fakeside, fakefloor, fakeceiling, sec, thingShade, foggy, thingColormap); } - else if (!r_modelscene) - { - RenderSprite::Project(Thread, thing, sprite.pos, sprite.tex, sprite.spriteScale, sprite.renderflags, fakeside, fakefloor, fakeceiling, sec, thingShade, foggy, thingColormap); - } else { - int spritenum = thing->sprite; - bool isPicnumOverride = thing->picnum.isValid(); - FSpriteModelFrame *modelframe = isPicnumOverride ? nullptr : FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED)); - if (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 - { - RenderSprite::Project(Thread, thing, sprite.pos, sprite.tex, sprite.spriteScale, sprite.renderflags, fakeside, fakefloor, fakeceiling, sec, thingShade, foggy, thingColormap); - } + RenderSprite::Project(Thread, thing, sprite.pos, sprite.tex, sprite.spriteScale, sprite.renderflags, fakeside, fakefloor, fakeceiling, sec, thingShade, foggy, thingColormap); } } }