mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 06:42:12 +00:00
- Collect all PVS information first so that processing the individual sectors can be done on multiple threads
This commit is contained in:
parent
4101e9bf1d
commit
7a1274ab76
30 changed files with 630 additions and 265 deletions
|
@ -744,6 +744,7 @@ set ( SWRENDER_SOURCES
|
|||
|
||||
set( POLYRENDER_SOURCES
|
||||
polyrenderer/poly_renderer.cpp
|
||||
polyrenderer/poly_renderthread.cpp
|
||||
polyrenderer/scene/poly_scene.cpp
|
||||
polyrenderer/scene/poly_portal.cpp
|
||||
polyrenderer/scene/poly_cull.cpp
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "swrenderer/r_swcolormaps.h"
|
||||
#include "poly_draw_args.h"
|
||||
#include "swrenderer/viewport/r_viewport.h"
|
||||
#include "polyrenderer/poly_renderthread.h"
|
||||
|
||||
void PolyDrawArgs::SetTexture(const uint8_t *texels, int width, int height)
|
||||
{
|
||||
|
@ -125,12 +126,12 @@ void PolyDrawArgs::SetColor(uint32_t bgra, uint8_t palindex)
|
|||
}
|
||||
}
|
||||
|
||||
void PolyDrawArgs::DrawArray(const TriVertex *vertices, int vcount, PolyDrawMode mode)
|
||||
void PolyDrawArgs::DrawArray(PolyRenderThread *thread, const TriVertex *vertices, int vcount, PolyDrawMode mode)
|
||||
{
|
||||
mVertices = vertices;
|
||||
mVertexCount = vcount;
|
||||
mDrawMode = mode;
|
||||
PolyRenderer::Instance()->DrawQueue->Push<DrawPolyTrianglesCommand>(*this, PolyTriangleDrawer::is_mirror());
|
||||
thread->DrawQueue->Push<DrawPolyTrianglesCommand>(*this, PolyTriangleDrawer::is_mirror());
|
||||
}
|
||||
|
||||
void PolyDrawArgs::SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *tex, bool fullbright)
|
||||
|
@ -273,7 +274,7 @@ void RectDrawArgs::SetColor(uint32_t bgra, uint8_t palindex)
|
|||
}
|
||||
}
|
||||
|
||||
void RectDrawArgs::Draw(double x0, double x1, double y0, double y1, double u0, double u1, double v0, double v1)
|
||||
void RectDrawArgs::Draw(PolyRenderThread *thread, double x0, double x1, double y0, double y1, double u0, double u1, double v0, double v1)
|
||||
{
|
||||
mX0 = (float)x0;
|
||||
mX1 = (float)x1;
|
||||
|
@ -283,7 +284,7 @@ void RectDrawArgs::Draw(double x0, double x1, double y0, double y1, double u0, d
|
|||
mU1 = (float)u1;
|
||||
mV0 = (float)v0;
|
||||
mV1 = (float)v1;
|
||||
PolyRenderer::Instance()->DrawQueue->Push<DrawRectCommand>(*this);
|
||||
thread->DrawQueue->Push<DrawRectCommand>(*this);
|
||||
}
|
||||
|
||||
void RectDrawArgs::SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *tex, bool fullbright)
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "r_data/colormaps.h"
|
||||
#include "screen_triangle.h"
|
||||
|
||||
class PolyRenderThread;
|
||||
class FTexture;
|
||||
struct TriMatrix;
|
||||
|
||||
|
@ -63,7 +64,7 @@ public:
|
|||
void SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *texture, bool fullbright);
|
||||
void SetTransform(const TriMatrix *objectToClip) { mObjectToClip = objectToClip; }
|
||||
void SetColor(uint32_t bgra, uint8_t palindex);
|
||||
void DrawArray(const TriVertex *vertices, int vcount, PolyDrawMode mode = PolyDrawMode::Triangles);
|
||||
void DrawArray(PolyRenderThread *thread, const TriVertex *vertices, int vcount, PolyDrawMode mode = PolyDrawMode::Triangles);
|
||||
|
||||
const TriMatrix *ObjectToClip() const { return mObjectToClip; }
|
||||
const PolyClipPlane &ClipPlane(int index) const { return mClipPlane[index]; }
|
||||
|
@ -157,7 +158,7 @@ public:
|
|||
void SetStyle(TriBlendMode blendmode, double srcalpha = 1.0, double destalpha = 1.0) { mBlendMode = blendmode; mSrcAlpha = (uint32_t)(srcalpha * 256.0 + 0.5); mDestAlpha = (uint32_t)(destalpha * 256.0 + 0.5); }
|
||||
void SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *texture, bool fullbright);
|
||||
void SetColor(uint32_t bgra, uint8_t palindex);
|
||||
void Draw(double x0, double x1, double y0, double y1, double u0, double u1, double v0, double v1);
|
||||
void Draw(PolyRenderThread *thread, double x0, double x1, double y0, double y1, double u0, double u1, double v0, double v1);
|
||||
|
||||
const uint8_t *TexturePixels() const { return mTexturePixels; }
|
||||
int TextureWidth() const { return mTextureWidth; }
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "poly_renderer.cpp"
|
||||
#include "poly_renderthread.cpp"
|
||||
#include "drawers/poly_buffer.cpp"
|
||||
#include "drawers/poly_draw_args.cpp"
|
||||
#include "drawers/poly_triangle.cpp"
|
||||
|
|
|
@ -54,7 +54,6 @@ PolyRenderer *PolyRenderer::Instance()
|
|||
|
||||
PolyRenderer::PolyRenderer()
|
||||
{
|
||||
DrawQueue = std::make_shared<DrawerCommandQueue>(&FrameMemory);
|
||||
}
|
||||
|
||||
void PolyRenderer::RenderView(player_t *player)
|
||||
|
@ -75,12 +74,11 @@ void PolyRenderer::RenderView(player_t *player)
|
|||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->ShaderColormap() && RenderTarget->IsBgra() && !(r_shadercolormaps && screen->Accel2D))
|
||||
{
|
||||
DrawQueue->Push<ApplySpecialColormapRGBACommand>(cameraLight->ShaderColormap(), screen);
|
||||
Threads.MainThread()->DrawQueue->Push<ApplySpecialColormapRGBACommand>(cameraLight->ShaderColormap(), screen);
|
||||
}
|
||||
|
||||
DrawerThreads::Execute(DrawQueue);
|
||||
Threads.MainThread()->FlushDrawQueue();
|
||||
DrawerThreads::WaitForWorkers();
|
||||
DrawQueue->Clear();
|
||||
}
|
||||
|
||||
void PolyRenderer::RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int y, int width, int height, bool dontmaplines)
|
||||
|
@ -98,7 +96,7 @@ void PolyRenderer::RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int
|
|||
canvas->Lock(true);
|
||||
|
||||
RenderActorView(actor, dontmaplines);
|
||||
DrawerThreads::Execute(DrawQueue);
|
||||
Threads.MainThread()->FlushDrawQueue();
|
||||
DrawerThreads::WaitForWorkers();
|
||||
|
||||
canvas->Unlock();
|
||||
|
@ -141,9 +139,9 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines)
|
|||
SetupPerspectiveMatrix();
|
||||
MainPortal.SetViewpoint(WorldToClip, PolyClipPlane(0.0f, 0.0f, 0.0f, 1.0f), GetNextStencilValue());
|
||||
MainPortal.Render(0);
|
||||
Skydome.Render(WorldToClip);
|
||||
Skydome.Render(Threads.MainThread(), WorldToClip);
|
||||
MainPortal.RenderTranslucent(0);
|
||||
PlayerSprites.Render();
|
||||
PlayerSprites.Render(Threads.MainThread());
|
||||
|
||||
Viewpoint.camera->renderflags = savedflags;
|
||||
interpolator.RestoreInterpolations ();
|
||||
|
@ -158,7 +156,7 @@ void PolyRenderer::RenderRemainingPlayerSprites()
|
|||
|
||||
void PolyRenderer::ClearBuffers()
|
||||
{
|
||||
FrameMemory.Clear();
|
||||
Threads.Clear();
|
||||
PolyStencilBuffer::Instance()->Clear(RenderTarget->GetWidth(), RenderTarget->GetHeight(), 0);
|
||||
PolyZBuffer::Instance()->Resize(RenderTarget->GetPitch(), RenderTarget->GetHeight());
|
||||
NextStencilValue = 0;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "scene/poly_sky.h"
|
||||
#include "scene/poly_light.h"
|
||||
#include "swrenderer/r_memory.h"
|
||||
#include "poly_renderthread.h"
|
||||
|
||||
class AActor;
|
||||
class DCanvas;
|
||||
|
@ -54,8 +55,7 @@ public:
|
|||
|
||||
bool DontMapLines = false;
|
||||
|
||||
RenderMemory FrameMemory;
|
||||
DrawerCommandQueuePtr DrawQueue;
|
||||
PolyRenderThreads Threads;
|
||||
DCanvas *RenderTarget = nullptr;
|
||||
FViewWindow Viewwindow;
|
||||
FRenderViewpoint Viewpoint;
|
||||
|
|
265
src/polyrenderer/poly_renderthread.cpp
Normal file
265
src/polyrenderer/poly_renderthread.cpp
Normal file
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
** 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 "templates.h"
|
||||
#include "doomdef.h"
|
||||
#include "m_bbox.h"
|
||||
#include "i_system.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "p_setup.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "g_level.h"
|
||||
#include "p_effect.h"
|
||||
#include "doomstat.h"
|
||||
#include "r_state.h"
|
||||
#include "v_palette.h"
|
||||
#include "r_sky.h"
|
||||
#include "po_man.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "poly_renderthread.h"
|
||||
#include "poly_renderer.h"
|
||||
#include <mutex>
|
||||
|
||||
#ifdef WIN32
|
||||
void PeekThreadedErrorPane();
|
||||
#endif
|
||||
|
||||
EXTERN_CVAR(Bool, r_scene_multithreaded);
|
||||
|
||||
PolyRenderThread::PolyRenderThread(bool mainThread)
|
||||
{
|
||||
MainThread = mainThread;
|
||||
FrameMemory.reset(new RenderMemory());
|
||||
DrawQueue = std::make_shared<DrawerCommandQueue>(FrameMemory.get());
|
||||
}
|
||||
|
||||
PolyRenderThread::~PolyRenderThread()
|
||||
{
|
||||
}
|
||||
|
||||
void PolyRenderThread::FlushDrawQueue()
|
||||
{
|
||||
DrawerThreads::Execute(DrawQueue);
|
||||
|
||||
UsedDrawQueues.push_back(DrawQueue);
|
||||
DrawQueue.reset();
|
||||
|
||||
if (!FreeDrawQueues.empty())
|
||||
{
|
||||
DrawQueue = FreeDrawQueues.back();
|
||||
FreeDrawQueues.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawQueue = std::make_shared<DrawerCommandQueue>(FrameMemory.get());
|
||||
}
|
||||
}
|
||||
|
||||
void PolyRenderThread::PrepareTexture(FTexture *texture)
|
||||
{
|
||||
if (texture == nullptr)
|
||||
return;
|
||||
|
||||
// Textures may not have loaded/refreshed yet. The shared code doing
|
||||
// this is not thread safe. By calling GetPixels in a mutex lock we
|
||||
// make sure that only one thread is loading a texture at any given
|
||||
// time.
|
||||
//
|
||||
// It is critical that this function is called before any direct
|
||||
// calls to GetPixels for this to work.
|
||||
|
||||
static std::mutex loadmutex;
|
||||
|
||||
std::unique_lock<std::mutex> lock(loadmutex);
|
||||
|
||||
texture->GetPixels();
|
||||
const FTexture::Span *spans;
|
||||
texture->GetColumn(0, &spans);
|
||||
if (PolyRenderer::Instance()->RenderTarget->IsBgra())
|
||||
{
|
||||
texture->GetPixelsBgra();
|
||||
texture->GetColumnBgra(0, &spans);
|
||||
}
|
||||
}
|
||||
|
||||
void PolyRenderThread::PreparePolyObject(subsector_t *sub)
|
||||
{
|
||||
static std::mutex polyobjmutex;
|
||||
|
||||
std::unique_lock<std::mutex> lock(polyobjmutex);
|
||||
|
||||
if (sub->BSP == nullptr || sub->BSP->bDirty)
|
||||
{
|
||||
sub->BuildPolyBSP();
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PolyRenderThreads::PolyRenderThreads()
|
||||
{
|
||||
std::unique_ptr<PolyRenderThread> thread(new PolyRenderThread(true));
|
||||
Threads.push_back(std::move(thread));
|
||||
}
|
||||
|
||||
PolyRenderThreads::~PolyRenderThreads()
|
||||
{
|
||||
StopThreads();
|
||||
}
|
||||
|
||||
void PolyRenderThreads::Clear()
|
||||
{
|
||||
for (auto &thread : Threads)
|
||||
{
|
||||
thread->FrameMemory->Clear();
|
||||
thread->DrawQueue->Clear();
|
||||
|
||||
while (!thread->UsedDrawQueues.empty())
|
||||
{
|
||||
auto queue = thread->UsedDrawQueues.back();
|
||||
thread->UsedDrawQueues.pop_back();
|
||||
queue->Clear();
|
||||
thread->FreeDrawQueues.push_back(queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PolyRenderThreads::RenderThreadSlices(int totalcount, std::function<void(PolyRenderThread *)> workerCallback, std::function<void(PolyRenderThread *)> collectCallback)
|
||||
{
|
||||
WorkerCallback = workerCallback;
|
||||
|
||||
int numThreads = std::thread::hardware_concurrency();
|
||||
if (numThreads == 0)
|
||||
numThreads = 4;
|
||||
|
||||
if (!r_scene_multithreaded || !r_multithreaded)
|
||||
numThreads = 1;
|
||||
|
||||
if (numThreads != (int)Threads.size())
|
||||
{
|
||||
StopThreads();
|
||||
StartThreads(numThreads);
|
||||
}
|
||||
|
||||
// Setup threads:
|
||||
std::unique_lock<std::mutex> start_lock(start_mutex);
|
||||
for (int i = 0; i < numThreads; i++)
|
||||
{
|
||||
Threads[i]->Start = totalcount * i / numThreads;
|
||||
Threads[i]->End = totalcount * (i + 1) / numThreads;
|
||||
}
|
||||
run_id++;
|
||||
start_lock.unlock();
|
||||
|
||||
// Notify threads to run
|
||||
if (Threads.size() > 1)
|
||||
{
|
||||
start_condition.notify_all();
|
||||
}
|
||||
|
||||
// Do the main thread ourselves:
|
||||
RenderThreadSlice(MainThread());
|
||||
|
||||
// Wait for everyone to finish:
|
||||
if (Threads.size() > 1)
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
std::unique_lock<std::mutex> end_lock(end_mutex);
|
||||
finished_threads++;
|
||||
if (!end_condition.wait_for(end_lock, 5s, [&]() { return finished_threads == Threads.size(); }))
|
||||
{
|
||||
#ifdef WIN32
|
||||
PeekThreadedErrorPane();
|
||||
#endif
|
||||
// Invoke the crash reporter so that we can capture the call stack of whatever the hung worker thread is doing
|
||||
int *threadCrashed = nullptr;
|
||||
*threadCrashed = 0xdeadbeef;
|
||||
}
|
||||
finished_threads = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < numThreads; i++)
|
||||
{
|
||||
Threads[i]->FlushDrawQueue();
|
||||
}
|
||||
|
||||
WorkerCallback = {};
|
||||
|
||||
for (int i = 1; i < numThreads; i++)
|
||||
{
|
||||
collectCallback(Threads[i].get());
|
||||
}
|
||||
}
|
||||
|
||||
void PolyRenderThreads::RenderThreadSlice(PolyRenderThread *thread)
|
||||
{
|
||||
WorkerCallback(thread);
|
||||
}
|
||||
|
||||
void PolyRenderThreads::StartThreads(size_t numThreads)
|
||||
{
|
||||
while (Threads.size() < (size_t)numThreads)
|
||||
{
|
||||
std::unique_ptr<PolyRenderThread> thread(new PolyRenderThread(false));
|
||||
auto renderthread = thread.get();
|
||||
int start_run_id = run_id;
|
||||
thread->thread = std::thread([=]()
|
||||
{
|
||||
int last_run_id = start_run_id;
|
||||
while (true)
|
||||
{
|
||||
// Wait until we are signalled to run:
|
||||
std::unique_lock<std::mutex> start_lock(start_mutex);
|
||||
start_condition.wait(start_lock, [&]() { return run_id != last_run_id || shutdown_flag; });
|
||||
if (shutdown_flag)
|
||||
break;
|
||||
last_run_id = run_id;
|
||||
start_lock.unlock();
|
||||
|
||||
RenderThreadSlice(renderthread);
|
||||
|
||||
// Notify main thread that we finished:
|
||||
std::unique_lock<std::mutex> end_lock(end_mutex);
|
||||
finished_threads++;
|
||||
end_lock.unlock();
|
||||
end_condition.notify_all();
|
||||
}
|
||||
});
|
||||
Threads.push_back(std::move(thread));
|
||||
}
|
||||
}
|
||||
|
||||
void PolyRenderThreads::StopThreads()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(start_mutex);
|
||||
shutdown_flag = true;
|
||||
lock.unlock();
|
||||
start_condition.notify_all();
|
||||
while (Threads.size() > 1)
|
||||
{
|
||||
Threads.back()->thread.join();
|
||||
Threads.pop_back();
|
||||
}
|
||||
lock.lock();
|
||||
shutdown_flag = false;
|
||||
}
|
94
src/polyrenderer/poly_renderthread.h
Normal file
94
src/polyrenderer/poly_renderthread.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
** 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 <memory>
|
||||
#include <thread>
|
||||
#include "swrenderer/r_memory.h"
|
||||
|
||||
class DrawerCommandQueue;
|
||||
typedef std::shared_ptr<DrawerCommandQueue> DrawerCommandQueuePtr;
|
||||
class RenderMemory;
|
||||
|
||||
class PolyRenderThread
|
||||
{
|
||||
public:
|
||||
PolyRenderThread(bool mainThread = true);
|
||||
~PolyRenderThread();
|
||||
|
||||
void FlushDrawQueue();
|
||||
|
||||
int Start = 0;
|
||||
int End = 0;
|
||||
bool MainThread = false;
|
||||
|
||||
std::unique_ptr<RenderMemory> FrameMemory;
|
||||
DrawerCommandQueuePtr DrawQueue;
|
||||
|
||||
std::vector<PolyTranslucentObject *> TranslucentObjects;
|
||||
|
||||
std::vector<std::unique_ptr<PolyDrawSectorPortal>> SectorPortals;
|
||||
std::vector<std::unique_ptr<PolyDrawLinePortal>> LinePortals;
|
||||
|
||||
// Make sure texture can accessed safely
|
||||
void PrepareTexture(FTexture *texture);
|
||||
|
||||
// Setup poly object in a threadsafe manner
|
||||
void PreparePolyObject(subsector_t *sub);
|
||||
|
||||
private:
|
||||
std::thread thread;
|
||||
std::vector<DrawerCommandQueuePtr> UsedDrawQueues;
|
||||
std::vector<DrawerCommandQueuePtr> FreeDrawQueues;
|
||||
|
||||
friend class PolyRenderThreads;
|
||||
};
|
||||
|
||||
class PolyRenderThreads
|
||||
{
|
||||
public:
|
||||
PolyRenderThreads();
|
||||
~PolyRenderThreads();
|
||||
|
||||
void Clear();
|
||||
void RenderThreadSlices(int totalcount, std::function<void(PolyRenderThread *)> workerCallback, std::function<void(PolyRenderThread *)> collectCallback);
|
||||
|
||||
PolyRenderThread *MainThread() { return Threads.front().get(); }
|
||||
|
||||
private:
|
||||
void RenderThreadSlice(PolyRenderThread *thread);
|
||||
|
||||
void StartThreads(size_t numThreads);
|
||||
void StopThreads();
|
||||
|
||||
std::function<void(PolyRenderThread *)> WorkerCallback;
|
||||
|
||||
std::vector<std::unique_ptr<PolyRenderThread>> Threads;
|
||||
std::mutex start_mutex;
|
||||
std::condition_variable start_condition;
|
||||
bool shutdown_flag = false;
|
||||
int run_id = 0;
|
||||
std::mutex end_mutex;
|
||||
std::condition_variable end_condition;
|
||||
size_t finished_threads = 0;
|
||||
};
|
|
@ -30,7 +30,14 @@
|
|||
|
||||
void PolyCull::CullScene(const TriMatrix &worldToClip, const PolyClipPlane &portalClipPlane)
|
||||
{
|
||||
ClearSolidSegments();
|
||||
MarkViewFrustum();
|
||||
|
||||
PvsSectors.clear();
|
||||
PvsLineStart.clear();
|
||||
PvsLineVisible.clear();
|
||||
SeenSectors.clear();
|
||||
SubsectorDepths.clear();
|
||||
PortalClipPlane = portalClipPlane;
|
||||
|
||||
// Cull front to back
|
||||
|
@ -97,35 +104,49 @@ void PolyCull::CullSubsector(subsector_t *sub)
|
|||
FirstSkyHeight = false;
|
||||
}
|
||||
|
||||
uint32_t subsectorDepth = (uint32_t)PvsSectors.size();
|
||||
|
||||
// Mark that we need to render this
|
||||
PvsSectors.push_back(sub);
|
||||
PvsLineStart.push_back((uint32_t)PvsLineVisible.size());
|
||||
|
||||
DVector3 viewpos = PolyRenderer::Instance()->Viewpoint.Pos;
|
||||
|
||||
// Update culling info for further bsp clipping
|
||||
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||
{
|
||||
seg_t *line = &sub->firstline[i];
|
||||
if ((line->sidedef == nullptr || !(line->sidedef->Flags & WALLF_POLYOBJ)) && line->backsector == nullptr)
|
||||
|
||||
// Skip lines not facing viewer
|
||||
DVector2 pt1 = line->v1->fPos() - viewpos;
|
||||
DVector2 pt2 = line->v2->fPos() - viewpos;
|
||||
if (pt1.Y * (pt1.X - pt2.X) + pt1.X * (pt2.Y - pt1.Y) >= 0)
|
||||
{
|
||||
// Skip lines not facing viewer
|
||||
DVector2 pt1 = line->v1->fPos() - PolyRenderer::Instance()->Viewpoint.Pos;
|
||||
DVector2 pt2 = line->v2->fPos() - PolyRenderer::Instance()->Viewpoint.Pos;
|
||||
if (pt1.Y * (pt1.X - pt2.X) + pt1.X * (pt2.Y - pt1.Y) >= 0)
|
||||
continue;
|
||||
|
||||
// Skip line if entirely behind portal clipping plane
|
||||
if ((PortalClipPlane.A * line->v1->fX() + PortalClipPlane.B * line->v1->fY() + PortalClipPlane.D <= 0.0) ||
|
||||
(PortalClipPlane.A * line->v2->fX() + PortalClipPlane.B * line->v2->fY() + PortalClipPlane.D <= 0.0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
angle_t angle1, angle2;
|
||||
if (GetAnglesForLine(line->v1->fX(), line->v1->fY(), line->v2->fX(), line->v2->fY(), angle1, angle2))
|
||||
{
|
||||
MarkSegmentCulled(angle1, angle2);
|
||||
}
|
||||
PvsLineVisible.push_back(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip line if entirely behind portal clipping plane
|
||||
if ((PortalClipPlane.A * line->v1->fX() + PortalClipPlane.B * line->v1->fY() + PortalClipPlane.D <= 0.0) ||
|
||||
(PortalClipPlane.A * line->v2->fX() + PortalClipPlane.B * line->v2->fY() + PortalClipPlane.D <= 0.0))
|
||||
{
|
||||
PvsLineVisible.push_back(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
angle_t angle1, angle2;
|
||||
bool lineVisible = GetAnglesForLine(line->v1->fX(), line->v1->fY(), line->v2->fX(), line->v2->fY(), angle1, angle2);
|
||||
if (lineVisible && line->backsector == nullptr)
|
||||
{
|
||||
MarkSegmentCulled(angle1, angle2);
|
||||
}
|
||||
|
||||
// Mark if this line was visible
|
||||
PvsLineVisible.push_back(lineVisible);
|
||||
}
|
||||
|
||||
SeenSectors.insert(sub->sector);
|
||||
SubsectorDepths[sub] = subsectorDepth;
|
||||
}
|
||||
|
||||
void PolyCull::ClearSolidSegments()
|
||||
|
|
|
@ -23,23 +23,26 @@
|
|||
#pragma once
|
||||
|
||||
#include "polyrenderer/drawers/poly_triangle.h"
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
class PolyCull
|
||||
{
|
||||
public:
|
||||
void ClearSolidSegments();
|
||||
void CullScene(const TriMatrix &worldToClip, const PolyClipPlane &portalClipPlane);
|
||||
|
||||
bool GetAnglesForLine(double x1, double y1, double x2, double y2, angle_t &angle1, angle_t &angle2) const;
|
||||
void MarkSegmentCulled(angle_t angle1, angle_t angle2);
|
||||
bool IsSegmentCulled(angle_t angle1, angle_t angle2) const;
|
||||
void InvertSegments();
|
||||
void MarkViewFrustum();
|
||||
bool IsLineSegVisible(uint32_t subsectorDepth, uint32_t lineIndex)
|
||||
{
|
||||
return PvsLineVisible[PvsLineStart[subsectorDepth] + lineIndex];
|
||||
}
|
||||
|
||||
std::vector<subsector_t *> PvsSectors;
|
||||
double MaxCeilingHeight = 0.0;
|
||||
double MinFloorHeight = 0.0;
|
||||
|
||||
std::set<sector_t *> SeenSectors;
|
||||
std::unordered_map<subsector_t *, uint32_t> SubsectorDepths;
|
||||
|
||||
static angle_t PointToPseudoAngle(double x, double y);
|
||||
|
||||
private:
|
||||
|
@ -49,6 +52,13 @@ private:
|
|||
angle_t Start, End;
|
||||
};
|
||||
|
||||
void ClearSolidSegments();
|
||||
void MarkViewFrustum();
|
||||
|
||||
bool GetAnglesForLine(double x1, double y1, double x2, double y2, angle_t &angle1, angle_t &angle2) const;
|
||||
bool IsSegmentCulled(angle_t angle1, angle_t angle2) const;
|
||||
void InvertSegments();
|
||||
|
||||
void CullNode(void *node);
|
||||
void CullSubsector(subsector_t *sub);
|
||||
int PointOnSide(const DVector2 &pos, const node_t *node);
|
||||
|
@ -57,6 +67,8 @@ private:
|
|||
// Returns true if some part of the bbox might be visible.
|
||||
bool CheckBBox(float *bspcoord);
|
||||
|
||||
void MarkSegmentCulled(angle_t angle1, angle_t angle2);
|
||||
|
||||
std::vector<SolidSegment> SolidSegments;
|
||||
std::vector<SolidSegment> TempInvertSolidSegments;
|
||||
const int SolidCullScale = 3000;
|
||||
|
@ -64,5 +76,8 @@ private:
|
|||
|
||||
PolyClipPlane PortalClipPlane;
|
||||
|
||||
std::vector<uint32_t> PvsLineStart;
|
||||
std::vector<bool> PvsLineVisible;
|
||||
|
||||
static angle_t AngleToPseudo(angle_t ang);
|
||||
};
|
||||
|
|
|
@ -28,10 +28,11 @@
|
|||
#include "poly_decal.h"
|
||||
#include "polyrenderer/poly_renderer.h"
|
||||
#include "polyrenderer/scene/poly_light.h"
|
||||
#include "polyrenderer/poly_renderthread.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "swrenderer/scene/r_scene.h"
|
||||
|
||||
void RenderPolyDecal::RenderWallDecals(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, const seg_t *line, uint32_t stencilValue)
|
||||
void RenderPolyDecal::RenderWallDecals(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, const seg_t *line, uint32_t stencilValue)
|
||||
{
|
||||
if (line->linedef == nullptr && line->sidedef == nullptr)
|
||||
return;
|
||||
|
@ -39,11 +40,11 @@ void RenderPolyDecal::RenderWallDecals(const TriMatrix &worldToClip, const PolyC
|
|||
for (DBaseDecal *decal = line->sidedef->AttachedDecals; decal != nullptr; decal = decal->WallNext)
|
||||
{
|
||||
RenderPolyDecal render;
|
||||
render.Render(worldToClip, clipPlane, decal, line, stencilValue);
|
||||
render.Render(thread, worldToClip, clipPlane, decal, line, stencilValue);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPolyDecal::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t stencilValue)
|
||||
void RenderPolyDecal::Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t stencilValue)
|
||||
{
|
||||
if (decal->RenderFlags & RF_INVISIBLE || !viewactive || !decal->PicNum.isValid())
|
||||
return;
|
||||
|
@ -148,7 +149,7 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, const PolyClipPlane &
|
|||
|
||||
// Generate vertices for the decal
|
||||
|
||||
TriVertex *vertices = PolyRenderer::Instance()->FrameMemory.AllocMemory<TriVertex>(4);
|
||||
TriVertex *vertices = thread->FrameMemory->AllocMemory<TriVertex>(4);
|
||||
vertices[0].x = (float)decal_left.X;
|
||||
vertices[0].y = (float)decal_left.Y;
|
||||
vertices[0].z = (float)ztop;
|
||||
|
@ -193,7 +194,7 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, const PolyClipPlane &
|
|||
args.SetDepthTest(true);
|
||||
args.SetWriteStencil(false);
|
||||
args.SetWriteDepth(false);
|
||||
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
|
||||
args.DrawArray(thread, vertices, 4, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
|
||||
void RenderPolyDecal::GetDecalSectors(DBaseDecal *decal, const seg_t *line, sector_t **front, sector_t **back)
|
||||
|
|
|
@ -27,10 +27,10 @@
|
|||
class RenderPolyDecal
|
||||
{
|
||||
public:
|
||||
static void RenderWallDecals(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, const seg_t *line, uint32_t stencilValue);
|
||||
static void RenderWallDecals(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, const seg_t *line, uint32_t stencilValue);
|
||||
|
||||
private:
|
||||
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t stencilValue);
|
||||
void Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t stencilValue);
|
||||
|
||||
void GetDecalSectors(DBaseDecal *decal, const seg_t *line, sector_t **front, sector_t **back);
|
||||
double GetDecalZ(DBaseDecal *decal, const seg_t *line, sector_t *front, sector_t *back);
|
||||
|
|
|
@ -28,10 +28,11 @@
|
|||
#include "poly_particle.h"
|
||||
#include "polyrenderer/poly_renderer.h"
|
||||
#include "polyrenderer/scene/poly_light.h"
|
||||
#include "polyrenderer/poly_renderthread.h"
|
||||
|
||||
EXTERN_CVAR(Int, gl_particles_style)
|
||||
|
||||
void RenderPolyParticle::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t stencilValue)
|
||||
void RenderPolyParticle::Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t stencilValue)
|
||||
{
|
||||
DVector3 pos = particle->Pos;
|
||||
double psize = particle->size / 8.0;
|
||||
|
@ -45,7 +46,7 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, const PolyClipPlan
|
|||
{ pos.X + viewpoint.Sin * psize, pos.Y - viewpoint.Cos * psize }
|
||||
};
|
||||
|
||||
TriVertex *vertices = PolyRenderer::Instance()->FrameMemory.AllocMemory<TriVertex>(4);
|
||||
TriVertex *vertices = thread->FrameMemory->AllocMemory<TriVertex>(4);
|
||||
|
||||
bool foggy = false;
|
||||
int actualextralight = foggy ? 0 : viewpoint.extralight << 4;
|
||||
|
@ -85,7 +86,7 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, const PolyClipPlan
|
|||
args.SetWriteDepth(false);
|
||||
args.SetClipPlane(0, clipPlane);
|
||||
args.SetTexture(GetParticleTexture(), ParticleTextureSize, ParticleTextureSize);
|
||||
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
|
||||
args.DrawArray(thread, vertices, 4, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
|
||||
uint8_t *RenderPolyParticle::GetParticleTexture()
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
class RenderPolyParticle
|
||||
{
|
||||
public:
|
||||
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t stencilValue);
|
||||
void Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t stencilValue);
|
||||
|
||||
private:
|
||||
static uint8_t *GetParticleTexture();
|
||||
|
@ -45,10 +45,10 @@ class PolyTranslucentParticle : public PolyTranslucentObject
|
|||
public:
|
||||
PolyTranslucentParticle(particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue) : PolyTranslucentObject(subsectorDepth, 0.0), particle(particle), sub(sub), StencilValue(stencilValue) { }
|
||||
|
||||
void Render(const TriMatrix &worldToClip, const PolyClipPlane &portalPlane) override
|
||||
void Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &portalPlane) override
|
||||
{
|
||||
RenderPolyParticle spr;
|
||||
spr.Render(worldToClip, portalPlane, particle, sub, StencilValue + 1);
|
||||
spr.Render(thread, worldToClip, portalPlane, particle, sub, StencilValue + 1);
|
||||
}
|
||||
|
||||
particle_t *particle = nullptr;
|
||||
|
|
|
@ -30,21 +30,22 @@
|
|||
#include "polyrenderer/poly_renderer.h"
|
||||
#include "r_sky.h"
|
||||
#include "polyrenderer/scene/poly_light.h"
|
||||
#include "polyrenderer/poly_renderthread.h"
|
||||
#include "p_lnspec.h"
|
||||
|
||||
EXTERN_CVAR(Int, r_3dfloors)
|
||||
|
||||
void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals)
|
||||
void RenderPolyPlane::RenderPlanes(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals)
|
||||
{
|
||||
if (sub->sector->CenterFloor() == sub->sector->CenterCeiling())
|
||||
return;
|
||||
|
||||
RenderPolyPlane plane;
|
||||
plane.Render(worldToClip, clipPlane, sub, stencilValue, true, skyCeilingHeight, sectorPortals);
|
||||
plane.Render(worldToClip, clipPlane, sub, stencilValue, false, skyFloorHeight, sectorPortals);
|
||||
plane.Render(thread, worldToClip, clipPlane, sub, stencilValue, true, skyCeilingHeight, sectorPortals);
|
||||
plane.Render(thread, worldToClip, clipPlane, sub, stencilValue, false, skyFloorHeight, sectorPortals);
|
||||
}
|
||||
|
||||
void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals)
|
||||
void RenderPolyPlane::Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals)
|
||||
{
|
||||
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
||||
|
||||
|
@ -182,7 +183,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &
|
|||
|
||||
PolyPlaneUVTransform transform(ceiling ? frontsector->planes[sector_t::ceiling].xform : frontsector->planes[sector_t::floor].xform, tex);
|
||||
|
||||
TriVertex *vertices = PolyRenderer::Instance()->FrameMemory.AllocMemory<TriVertex>(sub->numlines);
|
||||
TriVertex *vertices = thread->FrameMemory->AllocMemory<TriVertex>(sub->numlines);
|
||||
|
||||
if (ceiling)
|
||||
{
|
||||
|
@ -232,7 +233,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &
|
|||
{
|
||||
args.SetTexture(tex);
|
||||
args.SetStyle(TriBlendMode::TextureOpaque);
|
||||
args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan);
|
||||
args.DrawArray(thread, vertices, sub->numlines, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -248,17 +249,17 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &
|
|||
|
||||
args.SetWriteColor(false);
|
||||
args.SetWriteDepth(false);
|
||||
args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan);
|
||||
args.DrawArray(thread, vertices, sub->numlines, PolyDrawMode::TriangleFan);
|
||||
|
||||
RenderSkyWalls(args, sub, frontsector, portal, polyportal, ceiling, skyHeight, transform);
|
||||
RenderSkyWalls(thread, args, sub, frontsector, portal, polyportal, ceiling, skyHeight, transform);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPolyPlane::RenderSkyWalls(PolyDrawArgs &args, subsector_t *sub, sector_t *frontsector, FSectorPortal *portal, PolyDrawSectorPortal *polyportal, bool ceiling, double skyHeight, const PolyPlaneUVTransform &transform)
|
||||
void RenderPolyPlane::RenderSkyWalls(PolyRenderThread *thread, PolyDrawArgs &args, subsector_t *sub, sector_t *frontsector, FSectorPortal *portal, PolyDrawSectorPortal *polyportal, bool ceiling, double skyHeight, const PolyPlaneUVTransform &transform)
|
||||
{
|
||||
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||
{
|
||||
TriVertex *wallvert = PolyRenderer::Instance()->FrameMemory.AllocMemory<TriVertex>(4);
|
||||
TriVertex *wallvert = thread->FrameMemory->AllocMemory<TriVertex>(4);
|
||||
|
||||
seg_t *line = &sub->firstline[i];
|
||||
|
||||
|
@ -324,7 +325,7 @@ void RenderPolyPlane::RenderSkyWalls(PolyDrawArgs &args, subsector_t *sub, secto
|
|||
wallvert[3] = transform.GetVertex(line->v1, skyHeight);
|
||||
}
|
||||
|
||||
args.DrawArray(wallvert, 4, PolyDrawMode::TriangleFan);
|
||||
args.DrawArray(thread, wallvert, 4, PolyDrawMode::TriangleFan);
|
||||
|
||||
if (portal)
|
||||
{
|
||||
|
@ -384,7 +385,7 @@ float PolyPlaneUVTransform::GetV(float x, float y) const
|
|||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Render3DFloorPlane::RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue, uint32_t subsectorDepth, std::vector<PolyTranslucentObject *> &translucentObjects)
|
||||
void Render3DFloorPlane::RenderPlanes(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue, uint32_t subsectorDepth, std::vector<PolyTranslucentObject *> &translucentObjects)
|
||||
{
|
||||
if (!r_3dfloors || sub->sector->CenterFloor() == sub->sector->CenterCeiling())
|
||||
return;
|
||||
|
@ -428,9 +429,9 @@ void Render3DFloorPlane::RenderPlanes(const TriMatrix &worldToClip, const PolyCl
|
|||
}
|
||||
|
||||
if (!plane.Masked)
|
||||
plane.Render(worldToClip, clipPlane);
|
||||
plane.Render(thread, worldToClip, clipPlane);
|
||||
else
|
||||
translucentObjects.push_back(PolyRenderer::Instance()->FrameMemory.NewObject<PolyTranslucent3DFloorPlane>(plane, subsectorDepth));
|
||||
translucentObjects.push_back(thread->FrameMemory->NewObject<PolyTranslucent3DFloorPlane>(plane, subsectorDepth));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -468,14 +469,14 @@ void Render3DFloorPlane::RenderPlanes(const TriMatrix &worldToClip, const PolyCl
|
|||
}
|
||||
|
||||
if (!plane.Masked)
|
||||
plane.Render(worldToClip, clipPlane);
|
||||
plane.Render(thread, worldToClip, clipPlane);
|
||||
else
|
||||
translucentObjects.push_back(PolyRenderer::Instance()->FrameMemory.NewObject<PolyTranslucent3DFloorPlane>(plane, subsectorDepth));
|
||||
translucentObjects.push_back(thread->FrameMemory->NewObject<PolyTranslucent3DFloorPlane>(plane, subsectorDepth));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Render3DFloorPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane)
|
||||
void Render3DFloorPlane::Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane)
|
||||
{
|
||||
FTextureID picnum = ceiling ? *fakeFloor->bottom.texture : *fakeFloor->top.texture;
|
||||
FTexture *tex = TexMan(picnum);
|
||||
|
@ -498,7 +499,7 @@ void Render3DFloorPlane::Render(const TriMatrix &worldToClip, const PolyClipPlan
|
|||
|
||||
PolyPlaneUVTransform xform(ceiling ? fakeFloor->top.model->planes[sector_t::ceiling].xform : fakeFloor->top.model->planes[sector_t::floor].xform, tex);
|
||||
|
||||
TriVertex *vertices = PolyRenderer::Instance()->FrameMemory.AllocMemory<TriVertex>(sub->numlines);
|
||||
TriVertex *vertices = thread->FrameMemory->AllocMemory<TriVertex>(sub->numlines);
|
||||
if (ceiling)
|
||||
{
|
||||
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||
|
@ -537,5 +538,5 @@ void Render3DFloorPlane::Render(const TriMatrix &worldToClip, const PolyClipPlan
|
|||
args.SetWriteStencil(true, stencilValue + 1);
|
||||
args.SetTexture(tex);
|
||||
args.SetClipPlane(0, clipPlane);
|
||||
args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan);
|
||||
args.DrawArray(thread, vertices, sub->numlines, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
|
|
|
@ -47,19 +47,19 @@ private:
|
|||
class RenderPolyPlane
|
||||
{
|
||||
public:
|
||||
static void RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals);
|
||||
static void RenderPlanes(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals);
|
||||
|
||||
private:
|
||||
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals);
|
||||
void RenderSkyWalls(PolyDrawArgs &args, subsector_t *sub, sector_t *frontsector, FSectorPortal *portal, PolyDrawSectorPortal *polyportal, bool ceiling, double skyHeight, const PolyPlaneUVTransform &transform);
|
||||
void Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals);
|
||||
void RenderSkyWalls(PolyRenderThread *thread, PolyDrawArgs &args, subsector_t *sub, sector_t *frontsector, FSectorPortal *portal, PolyDrawSectorPortal *polyportal, bool ceiling, double skyHeight, const PolyPlaneUVTransform &transform);
|
||||
};
|
||||
|
||||
class Render3DFloorPlane
|
||||
{
|
||||
public:
|
||||
static void RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue, uint32_t subsectorDepth, std::vector<PolyTranslucentObject *> &translucentObjects);
|
||||
static void RenderPlanes(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue, uint32_t subsectorDepth, std::vector<PolyTranslucentObject *> &translucentObjects);
|
||||
|
||||
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane);
|
||||
void Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane);
|
||||
|
||||
subsector_t *sub = nullptr;
|
||||
uint32_t stencilValue = 0;
|
||||
|
@ -75,9 +75,9 @@ class PolyTranslucent3DFloorPlane : public PolyTranslucentObject
|
|||
public:
|
||||
PolyTranslucent3DFloorPlane(Render3DFloorPlane plane, uint32_t subsectorDepth) : PolyTranslucentObject(subsectorDepth, 1e7), plane(plane) { }
|
||||
|
||||
void Render(const TriMatrix &worldToClip, const PolyClipPlane &portalPlane) override
|
||||
void Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &portalPlane) override
|
||||
{
|
||||
plane.Render(worldToClip, portalPlane);
|
||||
plane.Render(thread, worldToClip, portalPlane);
|
||||
}
|
||||
|
||||
Render3DFloorPlane plane;
|
||||
|
|
|
@ -35,7 +35,7 @@ EXTERN_CVAR(Bool, r_deathcamera)
|
|||
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor)
|
||||
EXTERN_CVAR(Bool, r_shadercolormaps)
|
||||
|
||||
void RenderPolyPlayerSprites::Render()
|
||||
void RenderPolyPlayerSprites::Render(PolyRenderThread *thread)
|
||||
{
|
||||
// This code cannot be moved directly to RenderRemainingSprites because the engine
|
||||
// draws the canvas textures between this call and the final call to RenderRemainingSprites..
|
||||
|
@ -143,7 +143,7 @@ void RenderPolyPlayerSprites::Render()
|
|||
|
||||
if ((psp->GetID() != PSP_TARGETCENTER || CrosshairImage == nullptr) && psp->GetCaller() != nullptr)
|
||||
{
|
||||
RenderSprite(psp, viewpoint.camera, bobx, boby, wx, wy, viewpoint.TicFrac, spriteshade, basecolormap, foggy);
|
||||
RenderSprite(thread, psp, viewpoint.camera, bobx, boby, wx, wy, viewpoint.TicFrac, spriteshade, basecolormap, foggy);
|
||||
}
|
||||
|
||||
psp = psp->GetNext();
|
||||
|
@ -180,7 +180,7 @@ void RenderPolyPlayerSprites::RenderRemainingSprites()
|
|||
AcceleratedSprites.Clear();
|
||||
}
|
||||
|
||||
void RenderPolyPlayerSprites::RenderSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac, int spriteshade, FDynamicColormap *basecolormap, bool foggy)
|
||||
void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *pspr, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac, int spriteshade, FDynamicColormap *basecolormap, bool foggy)
|
||||
{
|
||||
double tx;
|
||||
int x1;
|
||||
|
@ -454,7 +454,7 @@ void RenderPolyPlayerSprites::RenderSprite(DPSprite *pspr, AActor *owner, float
|
|||
}
|
||||
}
|
||||
|
||||
vis.Render();
|
||||
vis.Render(thread);
|
||||
}
|
||||
|
||||
fixed_t RenderPolyPlayerSprites::LightLevelToShade(int lightlevel, bool foggy)
|
||||
|
@ -475,7 +475,7 @@ fixed_t RenderPolyPlayerSprites::LightLevelToShade(int lightlevel, bool foggy)
|
|||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PolyNoAccelPlayerSprite::Render()
|
||||
void PolyNoAccelPlayerSprite::Render(PolyRenderThread *thread)
|
||||
{
|
||||
if (xscale == 0 || fabs(yscale) < (1.0f / 32000.0f))
|
||||
{ // scaled to 0; can't see
|
||||
|
@ -498,7 +498,7 @@ void PolyNoAccelPlayerSprite::Render()
|
|||
y1 = centerY - texturemid * yscale;
|
||||
y2 = y1 + pic->GetHeight() * yscale;
|
||||
}
|
||||
args.Draw(x1, x2, y1, y2, 0.0f, 1.0f, 0.0f, 1.0f);
|
||||
args.Draw(thread, x1, x2, y1, y2, 0.0f, 1.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -61,7 +61,7 @@ public:
|
|||
|
||||
short renderflags = 0;
|
||||
|
||||
void Render();
|
||||
void Render(PolyRenderThread *thread);
|
||||
};
|
||||
|
||||
class PolyHWAccelPlayerSprite
|
||||
|
@ -90,11 +90,11 @@ public:
|
|||
class RenderPolyPlayerSprites
|
||||
{
|
||||
public:
|
||||
void Render();
|
||||
void Render(PolyRenderThread *thread);
|
||||
void RenderRemainingSprites();
|
||||
|
||||
private:
|
||||
void RenderSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac, int spriteshade, FDynamicColormap *basecolormap, bool foggy);
|
||||
void RenderSprite(PolyRenderThread *thread, DPSprite *pspr, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac, int spriteshade, FDynamicColormap *basecolormap, bool foggy);
|
||||
static fixed_t LightLevelToShade(int lightlevel, bool foggy);
|
||||
|
||||
enum { BASEXCENTER = 160 };
|
||||
|
|
|
@ -68,7 +68,7 @@ void PolyDrawSectorPortal::Render(int portalDepth)
|
|||
|
||||
PolyClipPlane portalPlane(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
RenderPortal.SetViewpoint(worldToClip, portalPlane, StencilValue);
|
||||
RenderPortal.SetPortalSegments(Segments);
|
||||
//RenderPortal.SetPortalSegments(Segments);
|
||||
RenderPortal.Render(portalDepth);
|
||||
|
||||
RestoreGlobals();
|
||||
|
@ -202,7 +202,7 @@ void PolyDrawLinePortal::Render(int portalDepth)
|
|||
|
||||
RenderPortal.LastPortalLine = clipLine;
|
||||
RenderPortal.SetViewpoint(worldToClip, portalPlane, StencilValue);
|
||||
RenderPortal.SetPortalSegments(Segments);
|
||||
//RenderPortal.SetPortalSegments(Segments);
|
||||
RenderPortal.Render(portalDepth);
|
||||
|
||||
RestoreGlobals();
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
FSectorPortal *Portal = nullptr;
|
||||
uint32_t StencilValue = 0;
|
||||
std::vector<PolyPortalVertexRange> Shape;
|
||||
std::vector<PolyPortalSegment> Segments;
|
||||
//std::vector<PolyPortalSegment> Segments;
|
||||
|
||||
private:
|
||||
void SaveGlobals();
|
||||
|
@ -80,7 +80,7 @@ public:
|
|||
line_t *Mirror = nullptr;
|
||||
uint32_t StencilValue = 0;
|
||||
std::vector<PolyPortalVertexRange> Shape;
|
||||
std::vector<PolyPortalSegment> Segments;
|
||||
//std::vector<PolyPortalSegment> Segments;
|
||||
|
||||
private:
|
||||
void SaveGlobals();
|
||||
|
|
|
@ -54,57 +54,50 @@ void RenderPolyScene::SetViewpoint(const TriMatrix &worldToClip, const PolyClipP
|
|||
PortalPlane = portalPlane;
|
||||
}
|
||||
|
||||
void RenderPolyScene::SetPortalSegments(const std::vector<PolyPortalSegment> &segments)
|
||||
{
|
||||
if (!segments.empty())
|
||||
{
|
||||
Cull.ClearSolidSegments();
|
||||
for (const auto &segment : segments)
|
||||
{
|
||||
Cull.MarkSegmentCulled(segment.Start, segment.End);
|
||||
}
|
||||
Cull.InvertSegments();
|
||||
PortalSegmentsAdded = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
PortalSegmentsAdded = false;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPolyScene::Render(int portalDepth)
|
||||
{
|
||||
ClearBuffers();
|
||||
if (!PortalSegmentsAdded)
|
||||
Cull.ClearSolidSegments();
|
||||
Cull.MarkViewFrustum();
|
||||
PolyRenderThread *thread = PolyRenderer::Instance()->Threads.MainThread();
|
||||
|
||||
ClearBuffers(thread);
|
||||
Cull.CullScene(WorldToClip, PortalPlane);
|
||||
Cull.ClearSolidSegments();
|
||||
RenderSectors();
|
||||
RenderPortals(portalDepth);
|
||||
}
|
||||
|
||||
void RenderPolyScene::ClearBuffers()
|
||||
void RenderPolyScene::ClearBuffers(PolyRenderThread *thread)
|
||||
{
|
||||
SeenSectors.clear();
|
||||
SubsectorDepths.clear();
|
||||
TranslucentObjects.clear();
|
||||
SectorPortals.clear();
|
||||
LinePortals.clear();
|
||||
thread->TranslucentObjects.clear();
|
||||
thread->SectorPortals.clear();
|
||||
thread->LinePortals.clear();
|
||||
}
|
||||
|
||||
void RenderPolyScene::RenderSectors()
|
||||
{
|
||||
int count = (int)Cull.PvsSectors.size();
|
||||
PolyRenderThread *mainthread = PolyRenderer::Instance()->Threads.MainThread();
|
||||
|
||||
int totalcount = (int)Cull.PvsSectors.size();
|
||||
auto subsectors = Cull.PvsSectors.data();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
PolyRenderer::Instance()->Threads.RenderThreadSlices(totalcount, [&](PolyRenderThread *thread)
|
||||
{
|
||||
RenderSubsector(subsectors[i], i);
|
||||
}
|
||||
if (!thread->MainThread)
|
||||
{
|
||||
ClearBuffers(thread);
|
||||
}
|
||||
|
||||
int start = thread->Start;
|
||||
int end = thread->End;
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
RenderSubsector(thread, subsectors[i], i);
|
||||
}
|
||||
}, [&](PolyRenderThread *thread)
|
||||
{
|
||||
mainthread->TranslucentObjects.insert(mainthread->TranslucentObjects.end(), thread->TranslucentObjects.begin(), thread->TranslucentObjects.end());
|
||||
});
|
||||
}
|
||||
|
||||
void RenderPolyScene::RenderSubsector(subsector_t *sub, uint32_t subsectorDepth)
|
||||
void RenderPolyScene::RenderSubsector(PolyRenderThread *thread, subsector_t *sub, uint32_t subsectorDepth)
|
||||
{
|
||||
sector_t *frontsector = sub->sector;
|
||||
frontsector->MoreFlags |= SECF_DRAWN;
|
||||
|
@ -127,44 +120,43 @@ void RenderPolyScene::RenderSubsector(subsector_t *sub, uint32_t subsectorDepth)
|
|||
|
||||
if (sub->BSP->Nodes.Size() == 0)
|
||||
{
|
||||
RenderPolySubsector(&sub->BSP->Subsectors[0], subsectorDepth, frontsector);
|
||||
RenderPolySubsector(thread, &sub->BSP->Subsectors[0], subsectorDepth, frontsector);
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderPolyNode(&sub->BSP->Nodes.Last(), subsectorDepth, frontsector);
|
||||
RenderPolyNode(thread, &sub->BSP->Nodes.Last(), subsectorDepth, frontsector);
|
||||
}
|
||||
|
||||
Render3DFloorPlane::RenderPlanes(WorldToClip, PortalPlane, sub, StencilValue, subsectorDepth, TranslucentObjects);
|
||||
RenderPolyPlane::RenderPlanes(WorldToClip, PortalPlane, sub, StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, SectorPortals);
|
||||
Render3DFloorPlane::RenderPlanes(thread, WorldToClip, PortalPlane, sub, StencilValue, subsectorDepth, thread->TranslucentObjects);
|
||||
RenderPolyPlane::RenderPlanes(thread, WorldToClip, PortalPlane, sub, StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, thread->SectorPortals);
|
||||
}
|
||||
else
|
||||
{
|
||||
Render3DFloorPlane::RenderPlanes(WorldToClip, PortalPlane, sub, StencilValue, subsectorDepth, TranslucentObjects);
|
||||
RenderPolyPlane::RenderPlanes(WorldToClip, PortalPlane, sub, StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, SectorPortals);
|
||||
Render3DFloorPlane::RenderPlanes(thread, WorldToClip, PortalPlane, sub, StencilValue, subsectorDepth, thread->TranslucentObjects);
|
||||
RenderPolyPlane::RenderPlanes(thread, WorldToClip, PortalPlane, sub, StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, thread->SectorPortals);
|
||||
|
||||
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||
{
|
||||
seg_t *line = &sub->firstline[i];
|
||||
RenderLine(sub, line, frontsector, subsectorDepth);
|
||||
if (Cull.IsLineSegVisible(subsectorDepth, i))
|
||||
{
|
||||
seg_t *line = &sub->firstline[i];
|
||||
RenderLine(thread, sub, line, frontsector, subsectorDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mainBSP)
|
||||
{
|
||||
RenderMemory &memory = PolyRenderer::Instance()->FrameMemory;
|
||||
int subsectorIndex = sub->Index();
|
||||
for (int i = ParticlesInSubsec[subsectorIndex]; i != NO_PARTICLE; i = Particles[i].snext)
|
||||
{
|
||||
particle_t *particle = Particles + i;
|
||||
TranslucentObjects.push_back(memory.NewObject<PolyTranslucentParticle>(particle, sub, subsectorDepth, StencilValue));
|
||||
thread->TranslucentObjects.push_back(thread->FrameMemory->NewObject<PolyTranslucentParticle>(particle, sub, subsectorDepth, StencilValue));
|
||||
}
|
||||
}
|
||||
|
||||
SeenSectors.insert(sub->sector);
|
||||
SubsectorDepths[sub] = subsectorDepth;
|
||||
}
|
||||
|
||||
void RenderPolyScene::RenderPolyNode(void *node, uint32_t subsectorDepth, sector_t *frontsector)
|
||||
void RenderPolyScene::RenderPolyNode(PolyRenderThread *thread, void *node, uint32_t subsectorDepth, sector_t *frontsector)
|
||||
{
|
||||
while (!((size_t)node & 1)) // Keep going until found a subsector
|
||||
{
|
||||
|
@ -174,7 +166,7 @@ void RenderPolyScene::RenderPolyNode(void *node, uint32_t subsectorDepth, sector
|
|||
int side = PointOnSide(PolyRenderer::Instance()->Viewpoint.Pos, bsp);
|
||||
|
||||
// Recursively divide front space (toward the viewer).
|
||||
RenderPolyNode(bsp->children[side], subsectorDepth, frontsector);
|
||||
RenderPolyNode(thread, bsp->children[side], subsectorDepth, frontsector);
|
||||
|
||||
// Possibly divide back space (away from the viewer).
|
||||
side ^= 1;
|
||||
|
@ -187,10 +179,10 @@ void RenderPolyScene::RenderPolyNode(void *node, uint32_t subsectorDepth, sector
|
|||
}
|
||||
|
||||
subsector_t *sub = (subsector_t *)((uint8_t *)node - 1);
|
||||
RenderPolySubsector(sub, subsectorDepth, frontsector);
|
||||
RenderPolySubsector(thread, sub, subsectorDepth, frontsector);
|
||||
}
|
||||
|
||||
void RenderPolyScene::RenderPolySubsector(subsector_t *sub, uint32_t subsectorDepth, sector_t *frontsector)
|
||||
void RenderPolyScene::RenderPolySubsector(PolyRenderThread *thread, subsector_t *sub, uint32_t subsectorDepth, sector_t *frontsector)
|
||||
{
|
||||
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
||||
|
||||
|
@ -205,11 +197,6 @@ void RenderPolyScene::RenderPolySubsector(subsector_t *sub, uint32_t subsectorDe
|
|||
if (pt1.Y * (pt1.X - pt2.X) + pt1.X * (pt2.Y - pt1.Y) >= 0)
|
||||
continue;
|
||||
|
||||
// Cull wall if not visible
|
||||
angle_t angle1, angle2;
|
||||
if (!Cull.GetAnglesForLine(line->v1->fX(), line->v1->fY(), line->v2->fX(), line->v2->fY(), angle1, angle2))
|
||||
continue;
|
||||
|
||||
// Tell automap we saw this
|
||||
if (!PolyRenderer::Instance()->DontMapLines && line->linedef)
|
||||
{
|
||||
|
@ -217,11 +204,7 @@ void RenderPolyScene::RenderPolySubsector(subsector_t *sub, uint32_t subsectorDe
|
|||
sub->flags |= SSECF_DRAWN;
|
||||
}
|
||||
|
||||
// Render wall, and update culling info if its an occlusion blocker
|
||||
if (RenderPolyWall::RenderLine(WorldToClip, PortalPlane, line, frontsector, subsectorDepth, StencilValue, TranslucentObjects, LinePortals, LastPortalLine))
|
||||
{
|
||||
Cull.MarkSegmentCulled(angle1, angle2);
|
||||
}
|
||||
RenderPolyWall::RenderLine(thread, WorldToClip, PortalPlane, line, frontsector, subsectorDepth, StencilValue, thread->TranslucentObjects, thread->LinePortals, LastPortalLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -231,22 +214,22 @@ int RenderPolyScene::PointOnSide(const DVector2 &pos, const node_t *node)
|
|||
return DMulScale32(FLOAT2FIXED(pos.Y) - node->y, node->dx, node->x - FLOAT2FIXED(pos.X), node->dy) > 0;
|
||||
}
|
||||
|
||||
void RenderPolyScene::RenderSprite(AActor *thing, double sortDistance, const DVector2 &left, const DVector2 &right)
|
||||
void RenderPolyScene::RenderSprite(PolyRenderThread *thread, AActor *thing, double sortDistance, const DVector2 &left, const DVector2 &right)
|
||||
{
|
||||
if (level.nodes.Size() == 0)
|
||||
{
|
||||
subsector_t *sub = &level.subsectors[0];
|
||||
auto it = SubsectorDepths.find(sub);
|
||||
if (it != SubsectorDepths.end())
|
||||
TranslucentObjects.push_back(PolyRenderer::Instance()->FrameMemory.NewObject<PolyTranslucentThing>(thing, sub, it->second, sortDistance, 0.0f, 1.0f, StencilValue));
|
||||
auto it = Cull.SubsectorDepths.find(sub);
|
||||
if (it != Cull.SubsectorDepths.end())
|
||||
thread->TranslucentObjects.push_back(thread->FrameMemory->NewObject<PolyTranslucentThing>(thing, sub, it->second, sortDistance, 0.0f, 1.0f, StencilValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderSprite(thing, sortDistance, left, right, 0.0, 1.0, level.HeadNode());
|
||||
RenderSprite(thread, thing, sortDistance, left, right, 0.0, 1.0, level.HeadNode());
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPolyScene::RenderSprite(AActor *thing, double sortDistance, DVector2 left, DVector2 right, double t1, double t2, void *node)
|
||||
void RenderPolyScene::RenderSprite(PolyRenderThread *thread, AActor *thing, double sortDistance, DVector2 left, DVector2 right, double t1, double t2, void *node)
|
||||
{
|
||||
while (!((size_t)node & 1)) // Keep going until found a subsector
|
||||
{
|
||||
|
@ -268,7 +251,7 @@ void RenderPolyScene::RenderSprite(AActor *thing, double sortDistance, DVector2
|
|||
DVector2 mid = left * (1.0 - t) + right * t;
|
||||
double tmid = t1 * (1.0 - t) + t2 * t;
|
||||
|
||||
RenderSprite(thing, sortDistance, mid, right, tmid, t2, bsp->children[sideRight]);
|
||||
RenderSprite(thread, thing, sortDistance, mid, right, tmid, t2, bsp->children[sideRight]);
|
||||
right = mid;
|
||||
t2 = tmid;
|
||||
}
|
||||
|
@ -277,26 +260,13 @@ void RenderPolyScene::RenderSprite(AActor *thing, double sortDistance, DVector2
|
|||
|
||||
subsector_t *sub = (subsector_t *)((uint8_t *)node - 1);
|
||||
|
||||
auto it = SubsectorDepths.find(sub);
|
||||
if (it != SubsectorDepths.end())
|
||||
TranslucentObjects.push_back(PolyRenderer::Instance()->FrameMemory.NewObject<PolyTranslucentThing>(thing, sub, it->second, sortDistance, (float)t1, (float)t2, StencilValue));
|
||||
auto it = Cull.SubsectorDepths.find(sub);
|
||||
if (it != Cull.SubsectorDepths.end())
|
||||
thread->TranslucentObjects.push_back(thread->FrameMemory->NewObject<PolyTranslucentThing>(thing, sub, it->second, sortDistance, (float)t1, (float)t2, StencilValue));
|
||||
}
|
||||
|
||||
void RenderPolyScene::RenderLine(subsector_t *sub, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth)
|
||||
void RenderPolyScene::RenderLine(PolyRenderThread *thread, subsector_t *sub, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth)
|
||||
{
|
||||
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
||||
|
||||
// Reject lines not facing viewer
|
||||
DVector2 pt1 = line->v1->fPos() - viewpoint.Pos;
|
||||
DVector2 pt2 = line->v2->fPos() - viewpoint.Pos;
|
||||
if (pt1.Y * (pt1.X - pt2.X) + pt1.X * (pt2.Y - pt1.Y) >= 0)
|
||||
return;
|
||||
|
||||
// Cull wall if not visible
|
||||
angle_t angle1, angle2;
|
||||
if (!Cull.GetAnglesForLine(line->v1->fX(), line->v1->fY(), line->v2->fX(), line->v2->fY(), angle1, angle2))
|
||||
return;
|
||||
|
||||
// Tell automap we saw this
|
||||
if (!PolyRenderer::Instance()->DontMapLines && line->linedef)
|
||||
{
|
||||
|
@ -310,26 +280,25 @@ void RenderPolyScene::RenderLine(subsector_t *sub, seg_t *line, sector_t *fronts
|
|||
for (unsigned int i = 0; i < line->backsector->e->XFloor.ffloors.Size(); i++)
|
||||
{
|
||||
F3DFloor *fakeFloor = line->backsector->e->XFloor.ffloors[i];
|
||||
RenderPolyWall::Render3DFloorLine(WorldToClip, PortalPlane, line, frontsector, subsectorDepth, StencilValue, fakeFloor, TranslucentObjects);
|
||||
RenderPolyWall::Render3DFloorLine(thread, WorldToClip, PortalPlane, line, frontsector, subsectorDepth, StencilValue, fakeFloor, thread->TranslucentObjects);
|
||||
}
|
||||
}
|
||||
|
||||
// Render wall, and update culling info if its an occlusion blocker
|
||||
if (RenderPolyWall::RenderLine(WorldToClip, PortalPlane, line, frontsector, subsectorDepth, StencilValue, TranslucentObjects, LinePortals, LastPortalLine))
|
||||
{
|
||||
Cull.MarkSegmentCulled(angle1, angle2);
|
||||
}
|
||||
RenderPolyWall::RenderLine(thread, WorldToClip, PortalPlane, line, frontsector, subsectorDepth, StencilValue, thread->TranslucentObjects, thread->LinePortals, LastPortalLine);
|
||||
}
|
||||
|
||||
void RenderPolyScene::RenderPortals(int portalDepth)
|
||||
{
|
||||
PolyRenderThread *thread = PolyRenderer::Instance()->Threads.MainThread();
|
||||
|
||||
bool foggy = false;
|
||||
if (portalDepth < r_portal_recursions)
|
||||
{
|
||||
for (auto &portal : SectorPortals)
|
||||
for (auto &portal : thread->SectorPortals)
|
||||
portal->Render(portalDepth + 1);
|
||||
|
||||
for (auto &portal : LinePortals)
|
||||
for (auto &portal : thread->LinePortals)
|
||||
portal->Render(portalDepth + 1);
|
||||
}
|
||||
else // Fill with black
|
||||
|
@ -341,25 +310,25 @@ void RenderPolyScene::RenderPortals(int portalDepth)
|
|||
args.SetClipPlane(0, PortalPlane);
|
||||
args.SetStyle(TriBlendMode::FillOpaque);
|
||||
|
||||
for (auto &portal : SectorPortals)
|
||||
for (auto &portal : thread->SectorPortals)
|
||||
{
|
||||
args.SetStencilTestValue(portal->StencilValue);
|
||||
args.SetWriteStencil(true, portal->StencilValue + 1);
|
||||
for (const auto &verts : portal->Shape)
|
||||
{
|
||||
args.SetFaceCullCCW(verts.Ccw);
|
||||
args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
|
||||
args.DrawArray(thread, verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &portal : LinePortals)
|
||||
for (auto &portal : thread->LinePortals)
|
||||
{
|
||||
args.SetStencilTestValue(portal->StencilValue);
|
||||
args.SetWriteStencil(true, portal->StencilValue + 1);
|
||||
for (const auto &verts : portal->Shape)
|
||||
{
|
||||
args.SetFaceCullCCW(verts.Ccw);
|
||||
args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
|
||||
args.DrawArray(thread, verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -367,9 +336,11 @@ void RenderPolyScene::RenderPortals(int portalDepth)
|
|||
|
||||
void RenderPolyScene::RenderTranslucent(int portalDepth)
|
||||
{
|
||||
PolyRenderThread *thread = PolyRenderer::Instance()->Threads.MainThread();
|
||||
|
||||
if (portalDepth < r_portal_recursions)
|
||||
{
|
||||
for (auto it = SectorPortals.rbegin(); it != SectorPortals.rend(); ++it)
|
||||
for (auto it = thread->SectorPortals.rbegin(); it != thread->SectorPortals.rend(); ++it)
|
||||
{
|
||||
auto &portal = *it;
|
||||
portal->RenderTranslucent(portalDepth + 1);
|
||||
|
@ -383,11 +354,11 @@ void RenderPolyScene::RenderTranslucent(int portalDepth)
|
|||
{
|
||||
args.SetFaceCullCCW(verts.Ccw);
|
||||
args.SetWriteColor(false);
|
||||
args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
|
||||
args.DrawArray(thread, verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it = LinePortals.rbegin(); it != LinePortals.rend(); ++it)
|
||||
for (auto it = thread->LinePortals.rbegin(); it != thread->LinePortals.rend(); ++it)
|
||||
{
|
||||
auto &portal = *it;
|
||||
portal->RenderTranslucent(portalDepth + 1);
|
||||
|
@ -401,13 +372,13 @@ void RenderPolyScene::RenderTranslucent(int portalDepth)
|
|||
{
|
||||
args.SetFaceCullCCW(verts.Ccw);
|
||||
args.SetWriteColor(false);
|
||||
args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
|
||||
args.DrawArray(thread, verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
||||
for (sector_t *sector : SeenSectors)
|
||||
for (sector_t *sector : Cull.SeenSectors)
|
||||
{
|
||||
for (AActor *thing = sector->thinglist; thing != nullptr; thing = thing->snext)
|
||||
{
|
||||
|
@ -415,18 +386,18 @@ void RenderPolyScene::RenderTranslucent(int portalDepth)
|
|||
if (!RenderPolySprite::GetLine(thing, left, right))
|
||||
continue;
|
||||
double distanceSquared = (thing->Pos() - viewpoint.Pos).LengthSquared();
|
||||
RenderSprite(thing, distanceSquared, left, right);
|
||||
RenderSprite(thread, thing, distanceSquared, left, right);
|
||||
}
|
||||
}
|
||||
|
||||
std::stable_sort(TranslucentObjects.begin(), TranslucentObjects.end(), [](auto a, auto b) { return *a < *b; });
|
||||
std::stable_sort(thread->TranslucentObjects.begin(), thread->TranslucentObjects.end(), [](auto a, auto b) { return *a < *b; });
|
||||
|
||||
for (auto it = TranslucentObjects.rbegin(); it != TranslucentObjects.rend(); ++it)
|
||||
for (auto it = thread->TranslucentObjects.rbegin(); it != thread->TranslucentObjects.rend(); ++it)
|
||||
{
|
||||
PolyTranslucentObject *obj = *it;
|
||||
obj->Render(WorldToClip, PortalPlane);
|
||||
obj->Render(thread, WorldToClip, PortalPlane);
|
||||
obj->~PolyTranslucentObject();
|
||||
}
|
||||
|
||||
TranslucentObjects.clear();
|
||||
thread->TranslucentObjects.clear();
|
||||
}
|
||||
|
|
|
@ -31,8 +31,6 @@
|
|||
#include "polyrenderer/drawers/poly_triangle.h"
|
||||
#include "poly_playersprite.h"
|
||||
#include "poly_cull.h"
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
class PolyTranslucentObject
|
||||
{
|
||||
|
@ -40,7 +38,7 @@ public:
|
|||
PolyTranslucentObject(uint32_t subsectorDepth = 0, double distanceSquared = 0.0) : subsectorDepth(subsectorDepth), DistanceSquared(distanceSquared) { }
|
||||
virtual ~PolyTranslucentObject() { }
|
||||
|
||||
virtual void Render(const TriMatrix &worldToClip, const PolyClipPlane &portalPlane) = 0;
|
||||
virtual void Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &portalPlane) = 0;
|
||||
|
||||
bool operator<(const PolyTranslucentObject &other) const
|
||||
{
|
||||
|
@ -62,7 +60,6 @@ public:
|
|||
RenderPolyScene();
|
||||
~RenderPolyScene();
|
||||
void SetViewpoint(const TriMatrix &worldToClip, const PolyClipPlane &portalPlane, uint32_t stencilValue);
|
||||
void SetPortalSegments(const std::vector<PolyPortalSegment> &segments);
|
||||
void Render(int portalDepth);
|
||||
void RenderTranslucent(int portalDepth);
|
||||
|
||||
|
@ -71,27 +68,21 @@ public:
|
|||
line_t *LastPortalLine = nullptr;
|
||||
|
||||
private:
|
||||
void ClearBuffers();
|
||||
void ClearBuffers(PolyRenderThread *thread);
|
||||
void RenderPortals(int portalDepth);
|
||||
void RenderSectors();
|
||||
void RenderSubsector(subsector_t *sub, uint32_t subsectorDepth);
|
||||
void RenderLine(subsector_t *sub, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth);
|
||||
void RenderSprite(AActor *thing, double sortDistance, const DVector2 &left, const DVector2 &right);
|
||||
void RenderSprite(AActor *thing, double sortDistance, DVector2 left, DVector2 right, double t1, double t2, void *node);
|
||||
void RenderSubsector(PolyRenderThread *thread, subsector_t *sub, uint32_t subsectorDepth);
|
||||
void RenderLine(PolyRenderThread *thread, subsector_t *sub, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth);
|
||||
void RenderSprite(PolyRenderThread *thread, AActor *thing, double sortDistance, const DVector2 &left, const DVector2 &right);
|
||||
void RenderSprite(PolyRenderThread *thread, AActor *thing, double sortDistance, DVector2 left, DVector2 right, double t1, double t2, void *node);
|
||||
|
||||
void RenderPolySubsector(subsector_t *sub, uint32_t subsectorDepth, sector_t *frontsector);
|
||||
void RenderPolyNode(void *node, uint32_t subsectorDepth, sector_t *frontsector);
|
||||
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);
|
||||
static int PointOnSide(const DVector2 &pos, const node_t *node);
|
||||
|
||||
TriMatrix WorldToClip;
|
||||
PolyClipPlane PortalPlane;
|
||||
uint32_t StencilValue = 0;
|
||||
PolyCull Cull;
|
||||
std::set<sector_t *> SeenSectors;
|
||||
std::unordered_map<subsector_t *, uint32_t> SubsectorDepths;
|
||||
std::vector<PolyTranslucentObject *> TranslucentObjects;
|
||||
|
||||
std::vector<std::unique_ptr<PolyDrawSectorPortal>> SectorPortals;
|
||||
std::vector<std::unique_ptr<PolyDrawLinePortal>> LinePortals;
|
||||
bool PortalSegmentsAdded = false;
|
||||
};
|
||||
|
|
|
@ -35,7 +35,7 @@ PolySkyDome::PolySkyDome()
|
|||
CreateDome();
|
||||
}
|
||||
|
||||
void PolySkyDome::Render(const TriMatrix &worldToClip)
|
||||
void PolySkyDome::Render(PolyRenderThread *thread, const TriMatrix &worldToClip)
|
||||
{
|
||||
#ifdef USE_GL_DOME_MATH
|
||||
TriMatrix modelMatrix = GLSkyMath();
|
||||
|
@ -88,8 +88,8 @@ void PolySkyDome::Render(const TriMatrix &worldToClip)
|
|||
args.SetWriteStencil(true, 1);
|
||||
args.SetClipPlane(0, PolyClipPlane(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
|
||||
RenderCapColorRow(args, mCurrentSetup.frontskytex, 0, false);
|
||||
RenderCapColorRow(args, mCurrentSetup.frontskytex, rc, true);
|
||||
RenderCapColorRow(thread, args, mCurrentSetup.frontskytex, 0, false);
|
||||
RenderCapColorRow(thread, args, mCurrentSetup.frontskytex, rc, true);
|
||||
|
||||
args.SetTexture(mCurrentSetup.frontskytex);
|
||||
|
||||
|
@ -100,20 +100,20 @@ void PolySkyDome::Render(const TriMatrix &worldToClip)
|
|||
|
||||
for (int i = 1; i <= mRows; i++)
|
||||
{
|
||||
RenderRow(args, i, topcapcolor, topcapindex);
|
||||
RenderRow(args, rc + i, bottomcapcolor, bottomcapindex);
|
||||
RenderRow(thread, args, i, topcapcolor, topcapindex);
|
||||
RenderRow(thread, args, rc + i, bottomcapcolor, bottomcapindex);
|
||||
}
|
||||
}
|
||||
|
||||
void PolySkyDome::RenderRow(PolyDrawArgs &args, int row, uint32_t capcolor, uint8_t capcolorindex)
|
||||
void PolySkyDome::RenderRow(PolyRenderThread *thread, PolyDrawArgs &args, int row, uint32_t capcolor, uint8_t capcolorindex)
|
||||
{
|
||||
args.SetFaceCullCCW(false);
|
||||
args.SetColor(capcolor, capcolorindex);
|
||||
args.SetStyle(TriBlendMode::Skycap);
|
||||
args.DrawArray(&mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], PolyDrawMode::TriangleStrip);
|
||||
args.DrawArray(thread, &mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], PolyDrawMode::TriangleStrip);
|
||||
}
|
||||
|
||||
void PolySkyDome::RenderCapColorRow(PolyDrawArgs &args, FTexture *skytex, int row, bool bottomCap)
|
||||
void PolySkyDome::RenderCapColorRow(PolyRenderThread *thread, PolyDrawArgs &args, FTexture *skytex, int row, bool bottomCap)
|
||||
{
|
||||
uint32_t solid = skytex->GetSkyCapColor(bottomCap);
|
||||
uint8_t palsolid = RGB32k.RGB[(RPART(solid) >> 3)][(GPART(solid) >> 3)][(BPART(solid) >> 3)];
|
||||
|
@ -121,7 +121,7 @@ void PolySkyDome::RenderCapColorRow(PolyDrawArgs &args, FTexture *skytex, int ro
|
|||
args.SetFaceCullCCW(bottomCap);
|
||||
args.SetColor(solid, palsolid);
|
||||
args.SetStyle(TriBlendMode::FillOpaque);
|
||||
args.DrawArray(&mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], PolyDrawMode::TriangleFan);
|
||||
args.DrawArray(thread, &mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], PolyDrawMode::TriangleFan);
|
||||
}
|
||||
|
||||
void PolySkyDome::CreateDome()
|
||||
|
|
|
@ -46,7 +46,7 @@ class PolySkyDome
|
|||
{
|
||||
public:
|
||||
PolySkyDome();
|
||||
void Render(const TriMatrix &worldToClip);
|
||||
void Render(PolyRenderThread *thread, const TriMatrix &worldToClip);
|
||||
|
||||
private:
|
||||
TArray<FVector2> mInitialUV;
|
||||
|
@ -58,8 +58,8 @@ private:
|
|||
void SkyVertex(int r, int c, bool yflip);
|
||||
void CreateSkyHemisphere(bool zflip);
|
||||
void CreateDome();
|
||||
void RenderRow(PolyDrawArgs &args, int row, uint32_t capcolor, uint8_t capcolorindex);
|
||||
void RenderCapColorRow(PolyDrawArgs &args, FTexture *skytex, int row, bool bottomCap);
|
||||
void RenderRow(PolyRenderThread *thread, PolyDrawArgs &args, int row, uint32_t capcolor, uint8_t capcolorindex);
|
||||
void RenderCapColorRow(PolyRenderThread *thread, PolyDrawArgs &args, FTexture *skytex, int row, bool bottomCap);
|
||||
|
||||
TriVertex SetVertexXYZ(float xx, float yy, float zz, float uu = 0, float vv = 0);
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "poly_sprite.h"
|
||||
#include "polyrenderer/poly_renderer.h"
|
||||
#include "polyrenderer/scene/poly_light.h"
|
||||
#include "polyrenderer/poly_renderthread.h"
|
||||
#include "r_data/r_vanillatrans.h"
|
||||
#include "actorinlines.h"
|
||||
|
||||
|
@ -71,7 +72,7 @@ bool RenderPolySprite::GetLine(AActor *thing, DVector2 &left, DVector2 &right)
|
|||
return true;
|
||||
}
|
||||
|
||||
void RenderPolySprite::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t stencilValue, float t1, float t2)
|
||||
void RenderPolySprite::Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t stencilValue, float t1, float t2)
|
||||
{
|
||||
DVector2 line[2];
|
||||
if (!GetLine(thing, line[0], line[1]))
|
||||
|
@ -116,7 +117,7 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, const PolyClipPlane
|
|||
// Rumor has it that AlterWeaponSprite needs to be called with visstyle passed in somewhere around here..
|
||||
//R_SetColorMapLight(visstyle.BaseColormap, 0, visstyle.ColormapNum << FRACBITS);
|
||||
|
||||
TriVertex *vertices = PolyRenderer::Instance()->FrameMemory.AllocMemory<TriVertex>(4);
|
||||
TriVertex *vertices = thread->FrameMemory->AllocMemory<TriVertex>(4);
|
||||
|
||||
bool foggy = false;
|
||||
int actualextralight = foggy ? 0 : viewpoint.extralight << 4;
|
||||
|
@ -166,7 +167,7 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, const PolyClipPlane
|
|||
args.SetDepthTest(true);
|
||||
args.SetWriteDepth(false);
|
||||
args.SetWriteStencil(false);
|
||||
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
|
||||
args.DrawArray(thread, vertices, 4, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
|
||||
double RenderPolySprite::GetSpriteFloorZ(AActor *thing, const DVector2 &thingpos)
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
class RenderPolySprite
|
||||
{
|
||||
public:
|
||||
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t stencilValue, float t1, float t2);
|
||||
void Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t stencilValue, float t1, float t2);
|
||||
|
||||
static bool GetLine(AActor *thing, DVector2 &left, DVector2 &right);
|
||||
static bool IsThingCulled(AActor *thing);
|
||||
|
@ -44,17 +44,17 @@ class PolyTranslucentThing : public PolyTranslucentObject
|
|||
public:
|
||||
PolyTranslucentThing(AActor *thing, subsector_t *sub, uint32_t subsectorDepth, double dist, float t1, float t2, uint32_t stencilValue) : PolyTranslucentObject(subsectorDepth, dist), thing(thing), sub(sub), SpriteLeft(t1), SpriteRight(t2), StencilValue(stencilValue) { }
|
||||
|
||||
void Render(const TriMatrix &worldToClip, const PolyClipPlane &portalPlane) override
|
||||
void Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &portalPlane) override
|
||||
{
|
||||
if ((thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE)
|
||||
{
|
||||
RenderPolyWallSprite wallspr;
|
||||
wallspr.Render(worldToClip, portalPlane, thing, sub, StencilValue + 1);
|
||||
wallspr.Render(thread, worldToClip, portalPlane, thing, sub, StencilValue + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderPolySprite spr;
|
||||
spr.Render(worldToClip, portalPlane, thing, sub, StencilValue + 1, SpriteLeft, SpriteRight);
|
||||
spr.Render(thread, worldToClip, portalPlane, thing, sub, StencilValue + 1, SpriteLeft, SpriteRight);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,12 +33,13 @@
|
|||
#include "polyrenderer/poly_renderer.h"
|
||||
#include "r_sky.h"
|
||||
#include "polyrenderer/scene/poly_light.h"
|
||||
#include "polyrenderer/poly_renderthread.h"
|
||||
#include "g_levellocals.h"
|
||||
|
||||
EXTERN_CVAR(Bool, r_drawmirrors)
|
||||
EXTERN_CVAR(Bool, r_fogboundary)
|
||||
|
||||
bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject*> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals, line_t *lastPortalLine)
|
||||
bool RenderPolyWall::RenderLine(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject*> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals, line_t *lastPortalLine)
|
||||
{
|
||||
double frontceilz1 = frontsector->ceilingplane.ZatPoint(line->v1);
|
||||
double frontfloorz1 = frontsector->floorplane.ZatPoint(line->v1);
|
||||
|
@ -105,7 +106,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const PolyClipPlan
|
|||
wall.Wallpart = side_t::mid;
|
||||
wall.Texture = GetTexture(wall.Line, wall.Side, side_t::mid);
|
||||
wall.Polyportal = polyportal;
|
||||
wall.Render(worldToClip, clipPlane);
|
||||
wall.Render(thread, worldToClip, clipPlane);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -141,7 +142,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const PolyClipPlan
|
|||
wall.BottomTexZ = MIN(MIN(backceilz1, frontceilz1), MIN(backceilz2, frontceilz2));
|
||||
wall.Wallpart = side_t::top;
|
||||
wall.Texture = GetTexture(wall.Line, wall.Side, side_t::top);
|
||||
wall.Render(worldToClip, clipPlane);
|
||||
wall.Render(thread, worldToClip, clipPlane);
|
||||
}
|
||||
|
||||
if ((bottomfloorz1 < bottomceilz1 || bottomfloorz2 < bottomceilz2) && line->sidedef && !bothSkyFloor)
|
||||
|
@ -153,7 +154,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const PolyClipPlan
|
|||
wall.UnpeggedCeil2 = topceilz2;
|
||||
wall.Wallpart = side_t::bottom;
|
||||
wall.Texture = GetTexture(wall.Line, wall.Side, side_t::bottom);
|
||||
wall.Render(worldToClip, clipPlane);
|
||||
wall.Render(thread, worldToClip, clipPlane);
|
||||
}
|
||||
|
||||
if (line->sidedef)
|
||||
|
@ -170,12 +171,12 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const PolyClipPlan
|
|||
|
||||
FTexture *midtex = TexMan(line->sidedef->GetTexture(side_t::mid), true);
|
||||
if ((midtex && midtex->UseType != FTexture::TEX_Null) || wall.FogBoundary)
|
||||
translucentWallsOutput.push_back(PolyRenderer::Instance()->FrameMemory.NewObject<PolyTranslucentWall>(wall));
|
||||
translucentWallsOutput.push_back(thread->FrameMemory->NewObject<PolyTranslucentWall>(wall));
|
||||
|
||||
if (polyportal)
|
||||
{
|
||||
wall.Polyportal = polyportal;
|
||||
wall.Render(worldToClip, clipPlane);
|
||||
wall.Render(thread, worldToClip, clipPlane);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +190,7 @@ bool RenderPolyWall::IsFogBoundary(sector_t *front, sector_t *back)
|
|||
(front->GetTexture(sector_t::ceiling) != skyflatnum || back->GetTexture(sector_t::ceiling) != skyflatnum);
|
||||
}
|
||||
|
||||
void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject*> &translucentWallsOutput)
|
||||
void RenderPolyWall::Render3DFloorLine(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject*> &translucentWallsOutput)
|
||||
{
|
||||
if (!(fakeFloor->flags & FF_EXISTS)) return;
|
||||
if (!(fakeFloor->flags & FF_RENDERPLANES)) return;
|
||||
|
@ -235,9 +236,9 @@ void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, const PolyC
|
|||
wall.Texture = GetTexture(wall.Line, wall.Side, side_t::mid);
|
||||
|
||||
if (!wall.Masked)
|
||||
wall.Render(worldToClip, clipPlane);
|
||||
wall.Render(thread, worldToClip, clipPlane);
|
||||
else
|
||||
translucentWallsOutput.push_back(PolyRenderer::Instance()->FrameMemory.NewObject<PolyTranslucentWall>(wall));
|
||||
translucentWallsOutput.push_back(thread->FrameMemory->NewObject<PolyTranslucentWall>(wall));
|
||||
}
|
||||
|
||||
void RenderPolyWall::SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2)
|
||||
|
@ -250,13 +251,13 @@ void RenderPolyWall::SetCoords(const DVector2 &v1, const DVector2 &v2, double ce
|
|||
this->floor2 = floor2;
|
||||
}
|
||||
|
||||
void RenderPolyWall::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane)
|
||||
void RenderPolyWall::Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane)
|
||||
{
|
||||
bool foggy = false;
|
||||
if (!Texture && !Polyportal && !FogBoundary)
|
||||
return;
|
||||
|
||||
TriVertex *vertices = PolyRenderer::Instance()->FrameMemory.AllocMemory<TriVertex>(4);
|
||||
TriVertex *vertices = thread->FrameMemory->AllocMemory<TriVertex>(4);
|
||||
|
||||
vertices[0].x = (float)v1.X;
|
||||
vertices[0].y = (float)v1.Y;
|
||||
|
@ -329,7 +330,7 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const PolyClipPlane &c
|
|||
args.SetDepthTest(true);
|
||||
args.SetWriteDepth(true);
|
||||
args.SetWriteStencil(false);
|
||||
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
|
||||
args.DrawArray(thread, vertices, 4, PolyDrawMode::TriangleFan);
|
||||
if (!Texture)
|
||||
return;
|
||||
}
|
||||
|
@ -339,13 +340,13 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const PolyClipPlane &c
|
|||
args.SetWriteStencil(true, Polyportal->StencilValue);
|
||||
args.SetWriteColor(false);
|
||||
args.SetWriteDepth(false);
|
||||
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
|
||||
args.DrawArray(thread, vertices, 4, PolyDrawMode::TriangleFan);
|
||||
Polyportal->Shape.push_back({ vertices, 4, true });
|
||||
}
|
||||
else if (!Masked)
|
||||
{
|
||||
args.SetStyle(TriBlendMode::TextureOpaque);
|
||||
DrawStripes(args, vertices);
|
||||
DrawStripes(thread, args, vertices);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -355,13 +356,13 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const PolyClipPlane &c
|
|||
args.SetDepthTest(true);
|
||||
args.SetWriteDepth(true);
|
||||
args.SetWriteStencil(false);
|
||||
DrawStripes(args, vertices);
|
||||
DrawStripes(thread, args, vertices);
|
||||
}
|
||||
|
||||
RenderPolyDecal::RenderWallDecals(worldToClip, clipPlane, LineSeg, StencilValue);
|
||||
RenderPolyDecal::RenderWallDecals(thread, worldToClip, clipPlane, LineSeg, StencilValue);
|
||||
}
|
||||
|
||||
void RenderPolyWall::DrawStripes(PolyDrawArgs &args, TriVertex *vertices)
|
||||
void RenderPolyWall::DrawStripes(PolyRenderThread *thread, PolyDrawArgs &args, TriVertex *vertices)
|
||||
{
|
||||
const auto &lightlist = Line->frontsector->e->XFloor.lightlist;
|
||||
if (lightlist.Size() > 0)
|
||||
|
@ -384,7 +385,7 @@ void RenderPolyWall::DrawStripes(PolyDrawArgs &args, TriVertex *vertices)
|
|||
|
||||
args.SetClipPlane(1, topPlane);
|
||||
args.SetClipPlane(2, bottomPlane);
|
||||
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
|
||||
args.DrawArray(thread, vertices, 4, PolyDrawMode::TriangleFan);
|
||||
|
||||
FDynamicColormap *basecolormap = GetColorTable(lit->extra_colormap, Line->frontsector->SpecialColors[sector_t::walltop]);
|
||||
|
||||
|
@ -407,11 +408,11 @@ void RenderPolyWall::DrawStripes(PolyDrawArgs &args, TriVertex *vertices)
|
|||
|
||||
args.SetClipPlane(1, topPlane);
|
||||
args.SetClipPlane(2, PolyClipPlane());
|
||||
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
|
||||
args.DrawArray(thread, vertices, 4, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
else
|
||||
{
|
||||
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
|
||||
args.DrawArray(thread, vertices, 4, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,11 +31,11 @@ class PolyCull;
|
|||
class RenderPolyWall
|
||||
{
|
||||
public:
|
||||
static bool RenderLine(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject*> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals, line_t *lastPortalLine);
|
||||
static void Render3DFloorLine(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject*> &translucentWallsOutput);
|
||||
static bool RenderLine(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject*> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals, line_t *lastPortalLine);
|
||||
static void Render3DFloorLine(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject*> &translucentWallsOutput);
|
||||
|
||||
void SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2);
|
||||
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane);
|
||||
void Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane);
|
||||
|
||||
DVector2 v1;
|
||||
DVector2 v2;
|
||||
|
@ -66,7 +66,7 @@ public:
|
|||
private:
|
||||
void ClampHeight(TriVertex &v1, TriVertex &v2);
|
||||
int GetLightLevel();
|
||||
void DrawStripes(PolyDrawArgs &args, TriVertex *vertices);
|
||||
void DrawStripes(PolyRenderThread *thread, PolyDrawArgs &args, TriVertex *vertices);
|
||||
|
||||
static bool IsFogBoundary(sector_t *front, sector_t *back);
|
||||
static FTexture *GetTexture(const line_t *Line, const side_t *Side, side_t::ETexpart texpart);
|
||||
|
@ -98,9 +98,9 @@ class PolyTranslucentWall : public PolyTranslucentObject
|
|||
public:
|
||||
PolyTranslucentWall(RenderPolyWall wall) : PolyTranslucentObject(wall.SubsectorDepth, 1e6), wall(wall) { }
|
||||
|
||||
void Render(const TriMatrix &worldToClip, const PolyClipPlane &portalPlane) override
|
||||
void Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &portalPlane) override
|
||||
{
|
||||
wall.Render(worldToClip, portalPlane);
|
||||
wall.Render(thread, worldToClip, portalPlane);
|
||||
}
|
||||
|
||||
RenderPolyWall wall;
|
||||
|
|
|
@ -28,8 +28,9 @@
|
|||
#include "poly_wallsprite.h"
|
||||
#include "polyrenderer/poly_renderer.h"
|
||||
#include "polyrenderer/scene/poly_light.h"
|
||||
#include "polyrenderer/poly_renderthread.h"
|
||||
|
||||
void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t stencilValue)
|
||||
void RenderPolyWallSprite::Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t stencilValue)
|
||||
{
|
||||
if (RenderPolySprite::IsThingCulled(thing))
|
||||
return;
|
||||
|
@ -69,7 +70,7 @@ void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const PolyClipPl
|
|||
|
||||
DVector2 points[2] = { left, right };
|
||||
|
||||
TriVertex *vertices = PolyRenderer::Instance()->FrameMemory.AllocMemory<TriVertex>(4);
|
||||
TriVertex *vertices = thread->FrameMemory->AllocMemory<TriVertex>(4);
|
||||
|
||||
bool foggy = false;
|
||||
int actualextralight = foggy ? 0 : viewpoint.extralight << 4;
|
||||
|
@ -110,5 +111,5 @@ void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const PolyClipPl
|
|||
args.SetWriteDepth(false);
|
||||
args.SetWriteStencil(false);
|
||||
args.SetStyle(TriBlendMode::TextureMasked);
|
||||
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
|
||||
args.DrawArray(thread, vertices, 4, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
|
|
|
@ -27,5 +27,5 @@
|
|||
class RenderPolyWallSprite
|
||||
{
|
||||
public:
|
||||
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t stencilValue);
|
||||
void Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t stencilValue);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue