mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
This commit is contained in:
commit
2b2297b73e
24 changed files with 862 additions and 1119 deletions
|
@ -937,7 +937,7 @@ void D_Display ()
|
|||
I_FreezeTime(false);
|
||||
GSnd->SetSfxPaused(false, 1);
|
||||
}
|
||||
|
||||
screen->End2D();
|
||||
cycles.Unclock();
|
||||
FrameCycles = cycles;
|
||||
}
|
||||
|
|
|
@ -370,6 +370,12 @@ void FDecalLib::ReadAllDecals ()
|
|||
for (i = 0; i < PClassActor::AllActorClasses.Size(); i++)
|
||||
{
|
||||
AActor *def = (AActor*)GetDefaultByType (PClassActor::AllActorClasses[i]);
|
||||
if (nullptr == def)
|
||||
{
|
||||
// This is referenced but undefined class
|
||||
// The corresponding warning should be already reported by DECORATE parser
|
||||
continue;
|
||||
}
|
||||
|
||||
FName v = ENamedName(intptr_t(def->DecalGenerator));
|
||||
if (v.IsValidName())
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "virtual.h"
|
||||
|
||||
|
||||
static int ThinkCount;
|
||||
static cycle_t ThinkCycles;
|
||||
extern cycle_t BotSupportCycles;
|
||||
extern cycle_t ActionCycles;
|
||||
|
@ -462,6 +463,7 @@ void DThinker::RunThinkers ()
|
|||
{
|
||||
int i, count;
|
||||
|
||||
ThinkCount = 0;
|
||||
ThinkCycles.Reset();
|
||||
BotSupportCycles.Reset();
|
||||
ActionCycles.Reset();
|
||||
|
@ -525,6 +527,7 @@ int DThinker::TickThinkers (FThinkerList *list, FThinkerList *dest)
|
|||
|
||||
if (!(node->ObjectFlags & OF_EuthanizeMe))
|
||||
{ // Only tick thinkers not scheduled for destruction
|
||||
ThinkCount++;
|
||||
node->CallTick();
|
||||
node->ObjectFlags &= ~OF_JustSpawned;
|
||||
GC::CheckGC();
|
||||
|
@ -753,6 +756,6 @@ DEFINE_ACTION_FUNCTION(DThinkerIterator, Reinit)
|
|||
ADD_STAT (think)
|
||||
{
|
||||
FString out;
|
||||
out.Format ("Think time = %04.2f ms, Action = %04.2f ms", ThinkCycles.TimeMS(), ActionCycles.TimeMS());
|
||||
out.Format ("Think time = %04.2f ms - %d thinkers, Action = %04.2f ms", ThinkCycles.TimeMS(), ThinkCount, ActionCycles.TimeMS());
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -359,8 +359,9 @@ FNativePalette *OpenGLFrameBuffer::CreatePalette(FRemapTable *remap)
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
bool OpenGLFrameBuffer::Begin2D(bool)
|
||||
bool OpenGLFrameBuffer::Begin2D(bool copy3d)
|
||||
{
|
||||
Super::Begin2D(copy3d);
|
||||
ClearClipRect();
|
||||
gl_RenderState.mViewMatrix.loadIdentity();
|
||||
gl_RenderState.mProjectionMatrix.ortho(0, GetWidth(), GetHeight(), 0, -1.0f, 1.0f);
|
||||
|
|
|
@ -33,7 +33,6 @@ public:
|
|||
OpenGLSWFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra);
|
||||
~OpenGLSWFrameBuffer();
|
||||
|
||||
bool HasBegun2D() override { return In2D || IsLocked(); }
|
||||
bool IsValid() override;
|
||||
bool Lock(bool buffered) override;
|
||||
void Unlock() override;
|
||||
|
|
|
@ -688,7 +688,7 @@ void gl_ParseBrightmap(FScanner &sc, int deflump)
|
|||
void AddAutoBrightmaps()
|
||||
{
|
||||
int num = Wads.GetNumLumps();
|
||||
for (unsigned i = 0; i < num; i++)
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
const char *name = Wads.GetLumpFullName(i);
|
||||
if (strstr(name, "brightmaps/auto/") == name)
|
||||
|
|
|
@ -268,7 +268,7 @@ template<typename BlendT, typename SamplerT>
|
|||
class TriScreenDrawer32
|
||||
{
|
||||
public:
|
||||
static void Execute(const TriDrawTriangleArgs *args, WorkerThreadData *thread)
|
||||
static void Execute(int x, int y, uint32_t mask0, uint32_t mask1, const TriDrawTriangleArgs *args)
|
||||
{
|
||||
using namespace TriScreenDrawerModes;
|
||||
|
||||
|
@ -281,44 +281,37 @@ public:
|
|||
if (is_simple_shade)
|
||||
{
|
||||
if (is_nearest_filter)
|
||||
Loop<SimpleShade, NearestFilter>(args, thread);
|
||||
DrawBlock<SimpleShade, NearestFilter>(x, y, mask0, mask1, args);
|
||||
else
|
||||
Loop<SimpleShade, LinearFilter>(args, thread);
|
||||
DrawBlock<SimpleShade, LinearFilter>(x, y, mask0, mask1, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_nearest_filter)
|
||||
Loop<AdvancedShade, NearestFilter>(args, thread);
|
||||
DrawBlock<AdvancedShade, NearestFilter>(x, y, mask0, mask1, args);
|
||||
else
|
||||
Loop<AdvancedShade, LinearFilter>(args, thread);
|
||||
DrawBlock<AdvancedShade, LinearFilter>(x, y, mask0, mask1, args);
|
||||
}
|
||||
}
|
||||
else // no linear filtering for translated, shaded, stencil, fill or skycap
|
||||
{
|
||||
if (is_simple_shade)
|
||||
{
|
||||
Loop<SimpleShade, NearestFilter>(args, thread);
|
||||
DrawBlock<SimpleShade, NearestFilter>(x, y, mask0, mask1, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
Loop<AdvancedShade, NearestFilter>(args, thread);
|
||||
DrawBlock<AdvancedShade, NearestFilter>(x, y, mask0, mask1, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename ShadeModeT, typename FilterModeT>
|
||||
FORCEINLINE static void VECTORCALL Loop(const TriDrawTriangleArgs *args, WorkerThreadData *thread)
|
||||
FORCEINLINE static void VECTORCALL DrawBlock(int destX, int destY, uint32_t mask0, uint32_t mask1, const TriDrawTriangleArgs *args)
|
||||
{
|
||||
using namespace TriScreenDrawerModes;
|
||||
|
||||
int numSpans = thread->NumFullSpans;
|
||||
auto fullSpans = thread->FullSpans;
|
||||
int numBlocks = thread->NumPartialBlocks;
|
||||
auto partialBlocks = thread->PartialBlocks;
|
||||
int startX = thread->StartX;
|
||||
int startY = thread->StartY;
|
||||
|
||||
bool is_fixed_light = args->uniforms->FixedLight();
|
||||
uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff;
|
||||
uint32_t srcalpha = args->uniforms->SrcAlpha();
|
||||
|
@ -326,24 +319,20 @@ private:
|
|||
|
||||
// Calculate gradients
|
||||
const TriVertex &v1 = *args->v1;
|
||||
const TriVertex &v2 = *args->v2;
|
||||
const TriVertex &v3 = *args->v3;
|
||||
ScreenTriangleStepVariables gradientX;
|
||||
ScreenTriangleStepVariables gradientY;
|
||||
ScreenTriangleStepVariables start;
|
||||
gradientX.W = FindGradientX(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.w, v2.w, v3.w);
|
||||
gradientY.W = FindGradientY(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.w, v2.w, v3.w);
|
||||
gradientX.U = FindGradientX(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.u * v1.w, v2.u * v2.w, v3.u * v3.w);
|
||||
gradientY.U = FindGradientY(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.u * v1.w, v2.u * v2.w, v3.u * v3.w);
|
||||
gradientX.V = FindGradientX(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.v * v1.w, v2.v * v2.w, v3.v * v3.w);
|
||||
gradientY.V = FindGradientY(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.v * v1.w, v2.v * v2.w, v3.v * v3.w);
|
||||
start.W = v1.w + gradientX.W * (startX - v1.x) + gradientY.W * (startY - v1.y);
|
||||
start.U = v1.u * v1.w + gradientX.U * (startX - v1.x) + gradientY.U * (startY - v1.y);
|
||||
start.V = v1.v * v1.w + gradientX.V * (startX - v1.x) + gradientY.V * (startY - v1.y);
|
||||
ScreenTriangleStepVariables gradientX = args->gradientX;
|
||||
ScreenTriangleStepVariables gradientY = args->gradientY;
|
||||
ScreenTriangleStepVariables blockPosY;
|
||||
blockPosY.W = v1.w + gradientX.W * (destX - v1.x) + gradientY.W * (destY - v1.y);
|
||||
blockPosY.U = v1.u * v1.w + gradientX.U * (destX - v1.x) + gradientY.U * (destY - v1.y);
|
||||
blockPosY.V = v1.v * v1.w + gradientX.V * (destX - v1.x) + gradientY.V * (destY - v1.y);
|
||||
gradientX.W *= 8.0f;
|
||||
gradientX.U *= 8.0f;
|
||||
gradientX.V *= 8.0f;
|
||||
|
||||
// Output
|
||||
uint32_t * RESTRICT destOrg = (uint32_t*)args->dest;
|
||||
int pitch = args->pitch;
|
||||
uint32_t *dest = destOrg + destX + destY * pitch;
|
||||
|
||||
// Light
|
||||
uint32_t light = args->uniforms->Light();
|
||||
|
@ -388,93 +377,78 @@ private:
|
|||
desaturate = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < numSpans; i++)
|
||||
if (mask0 == 0xffffffff && mask1 == 0xffffffff)
|
||||
{
|
||||
const auto &span = fullSpans[i];
|
||||
|
||||
uint32_t *dest = destOrg + span.X + span.Y * pitch;
|
||||
int width = span.Length;
|
||||
int height = 8;
|
||||
|
||||
ScreenTriangleStepVariables blockPosY;
|
||||
blockPosY.W = start.W + gradientX.W * (span.X - startX) + gradientY.W * (span.Y - startY);
|
||||
blockPosY.U = start.U + gradientX.U * (span.X - startX) + gradientY.U * (span.Y - startY);
|
||||
blockPosY.V = start.V + gradientX.V * (span.X - startX) + gradientY.V * (span.Y - startY);
|
||||
|
||||
for (int y = 0; y < height; y++)
|
||||
for (int y = 0; y < 8; y++)
|
||||
{
|
||||
ScreenTriangleStepVariables blockPosX = blockPosY;
|
||||
|
||||
float rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t posU = (int32_t)(blockPosX.U * rcpW);
|
||||
int32_t posV = (int32_t)(blockPosX.V * rcpW);
|
||||
float rcpW = 0x01000000 / blockPosY.W;
|
||||
int32_t posU = (int32_t)(blockPosY.U * rcpW);
|
||||
int32_t posV = (int32_t)(blockPosY.V * rcpW);
|
||||
|
||||
fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask);
|
||||
|
||||
for (int x = 0; x < width; x++)
|
||||
ScreenTriangleStepVariables blockPosX = blockPosY;
|
||||
blockPosX.W += gradientX.W;
|
||||
blockPosX.U += gradientX.U;
|
||||
blockPosX.V += gradientX.V;
|
||||
|
||||
rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t nextU = (int32_t)(blockPosX.U * rcpW);
|
||||
int32_t nextV = (int32_t)(blockPosX.V * rcpW);
|
||||
int32_t stepU = (nextU - posU) / 8;
|
||||
int32_t stepV = (nextV - posV) / 8;
|
||||
|
||||
fixed_t lightnext = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosX.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
fixed_t lightstep = (lightnext - lightpos) / 8;
|
||||
lightstep = lightstep & lightmask;
|
||||
|
||||
for (int ix = 0; ix < 4; ix++)
|
||||
{
|
||||
blockPosX.W += gradientX.W * 8;
|
||||
blockPosX.U += gradientX.U * 8;
|
||||
blockPosX.V += gradientX.V * 8;
|
||||
// Load bgcolor
|
||||
__m128i bgcolor;
|
||||
if (BlendT::Mode != (int)BlendModes::Opaque)
|
||||
bgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(dest + ix * 2)), _mm_setzero_si128());
|
||||
else
|
||||
bgcolor = _mm_setzero_si128();
|
||||
|
||||
rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t nextU = (int32_t)(blockPosX.U * rcpW);
|
||||
int32_t nextV = (int32_t)(blockPosX.V * rcpW);
|
||||
int32_t stepU = (nextU - posU) / 8;
|
||||
int32_t stepV = (nextV - posV) / 8;
|
||||
// Sample fgcolor
|
||||
unsigned int ifgcolor[2], ifgshade[2];
|
||||
ifgcolor[0] = Sample32<SamplerT, FilterModeT>(posU, posV, texPixels, texWidth, texHeight, oneU, oneV, color, translation);
|
||||
ifgshade[0] = SampleShade32<SamplerT>(posU, posV, texPixels, texWidth, texHeight);
|
||||
posU += stepU;
|
||||
posV += stepV;
|
||||
|
||||
fixed_t lightnext = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosX.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
fixed_t lightstep = (lightnext - lightpos) / 8;
|
||||
lightstep = lightstep & lightmask;
|
||||
ifgcolor[1] = Sample32<SamplerT, FilterModeT>(posU, posV, texPixels, texWidth, texHeight, oneU, oneV, color, translation);
|
||||
ifgshade[1] = SampleShade32<SamplerT>(posU, posV, texPixels, texWidth, texHeight);
|
||||
posU += stepU;
|
||||
posV += stepV;
|
||||
|
||||
for (int ix = 0; ix < 4; ix++)
|
||||
// Setup light
|
||||
int lightpos0 = lightpos >> 8;
|
||||
lightpos += lightstep;
|
||||
int lightpos1 = lightpos >> 8;
|
||||
lightpos += lightstep;
|
||||
__m128i mlight = _mm_set_epi16(256, lightpos1, lightpos1, lightpos1, 256, lightpos0, lightpos0, lightpos0);
|
||||
|
||||
__m128i shade_fade_lit;
|
||||
if (ShadeModeT::Mode == (int)ShadeMode::Advanced)
|
||||
{
|
||||
// Load bgcolor
|
||||
__m128i bgcolor;
|
||||
if (BlendT::Mode != (int)BlendModes::Opaque)
|
||||
bgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(dest + x * 8 + ix * 2)), _mm_setzero_si128());
|
||||
else
|
||||
bgcolor = _mm_setzero_si128();
|
||||
|
||||
// Sample fgcolor
|
||||
unsigned int ifgcolor[2], ifgshade[2];
|
||||
ifgcolor[0] = Sample32<SamplerT, FilterModeT>(posU, posV, texPixels, texWidth, texHeight, oneU, oneV, color, translation);
|
||||
ifgshade[0] = SampleShade32<SamplerT>(posU, posV, texPixels, texWidth, texHeight);
|
||||
posU += stepU;
|
||||
posV += stepV;
|
||||
|
||||
ifgcolor[1] = Sample32<SamplerT, FilterModeT>(posU, posV, texPixels, texWidth, texHeight, oneU, oneV, color, translation);
|
||||
ifgshade[1] = SampleShade32<SamplerT>(posU, posV, texPixels, texWidth, texHeight);
|
||||
posU += stepU;
|
||||
posV += stepV;
|
||||
|
||||
// Setup light
|
||||
int lightpos0 = lightpos >> 8;
|
||||
lightpos += lightstep;
|
||||
int lightpos1 = lightpos >> 8;
|
||||
lightpos += lightstep;
|
||||
__m128i mlight = _mm_set_epi16(256, lightpos1, lightpos1, lightpos1, 256, lightpos0, lightpos0, lightpos0);
|
||||
|
||||
__m128i shade_fade_lit;
|
||||
if (ShadeModeT::Mode == (int)ShadeMode::Advanced)
|
||||
{
|
||||
__m128i inv_light = _mm_sub_epi16(_mm_set_epi16(0, 256, 256, 256, 0, 256, 256, 256), mlight);
|
||||
shade_fade_lit = _mm_mullo_epi16(shade_fade, inv_light);
|
||||
}
|
||||
else
|
||||
{
|
||||
shade_fade_lit = _mm_setzero_si128();
|
||||
}
|
||||
|
||||
// Shade and blend
|
||||
__m128i fgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)ifgcolor), _mm_setzero_si128());
|
||||
fgcolor = Shade32<ShadeModeT>(fgcolor, mlight, ifgcolor[0], ifgcolor[1], desaturate, inv_desaturate, shade_fade_lit, shade_light);
|
||||
__m128i outcolor = Blend32<BlendT>(fgcolor, bgcolor, ifgcolor[0], ifgcolor[1], ifgshade[0], ifgshade[1], srcalpha, destalpha);
|
||||
|
||||
// Store result
|
||||
_mm_storel_epi64((__m128i*)(dest + x * 8 + ix * 2), outcolor);
|
||||
__m128i inv_light = _mm_sub_epi16(_mm_set_epi16(0, 256, 256, 256, 0, 256, 256, 256), mlight);
|
||||
shade_fade_lit = _mm_mullo_epi16(shade_fade, inv_light);
|
||||
}
|
||||
else
|
||||
{
|
||||
shade_fade_lit = _mm_setzero_si128();
|
||||
}
|
||||
|
||||
// Shade and blend
|
||||
__m128i fgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)ifgcolor), _mm_setzero_si128());
|
||||
fgcolor = Shade32<ShadeModeT>(fgcolor, mlight, ifgcolor[0], ifgcolor[1], desaturate, inv_desaturate, shade_fade_lit, shade_light);
|
||||
__m128i outcolor = Blend32<BlendT>(fgcolor, bgcolor, ifgcolor[0], ifgcolor[1], ifgshade[0], ifgshade[1], srcalpha, destalpha);
|
||||
|
||||
// Store result
|
||||
_mm_storel_epi64((__m128i*)(dest + ix * 2), outcolor);
|
||||
}
|
||||
|
||||
blockPosY.W += gradientY.W;
|
||||
|
@ -484,35 +458,22 @@ private:
|
|||
dest += pitch;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < numBlocks; i++)
|
||||
else
|
||||
{
|
||||
const auto &block = partialBlocks[i];
|
||||
|
||||
ScreenTriangleStepVariables blockPosY;
|
||||
blockPosY.W = start.W + gradientX.W * (block.X - startX) + gradientY.W * (block.Y - startY);
|
||||
blockPosY.U = start.U + gradientX.U * (block.X - startX) + gradientY.U * (block.Y - startY);
|
||||
blockPosY.V = start.V + gradientX.V * (block.X - startX) + gradientY.V * (block.Y - startY);
|
||||
|
||||
uint32_t *dest = destOrg + block.X + block.Y * pitch;
|
||||
uint32_t mask0 = block.Mask0;
|
||||
uint32_t mask1 = block.Mask1;
|
||||
|
||||
// mask0 loop:
|
||||
for (int y = 0; y < 4; y++)
|
||||
{
|
||||
ScreenTriangleStepVariables blockPosX = blockPosY;
|
||||
|
||||
float rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t posU = (int32_t)(blockPosX.U * rcpW);
|
||||
int32_t posV = (int32_t)(blockPosX.V * rcpW);
|
||||
float rcpW = 0x01000000 / blockPosY.W;
|
||||
int32_t posU = (int32_t)(blockPosY.U * rcpW);
|
||||
int32_t posV = (int32_t)(blockPosY.V * rcpW);
|
||||
|
||||
fixed_t lightpos = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask);
|
||||
|
||||
blockPosX.W += gradientX.W * 8;
|
||||
blockPosX.U += gradientX.U * 8;
|
||||
blockPosX.V += gradientX.V * 8;
|
||||
ScreenTriangleStepVariables blockPosX = blockPosY;
|
||||
blockPosX.W += gradientX.W;
|
||||
blockPosX.U += gradientX.U;
|
||||
blockPosX.V += gradientX.V;
|
||||
|
||||
rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t nextU = (int32_t)(blockPosX.U * rcpW);
|
||||
|
@ -590,18 +551,17 @@ private:
|
|||
// mask1 loop:
|
||||
for (int y = 0; y < 4; y++)
|
||||
{
|
||||
ScreenTriangleStepVariables blockPosX = blockPosY;
|
||||
|
||||
float rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t posU = (int32_t)(blockPosX.U * rcpW);
|
||||
int32_t posV = (int32_t)(blockPosX.V * rcpW);
|
||||
float rcpW = 0x01000000 / blockPosY.W;
|
||||
int32_t posU = (int32_t)(blockPosY.U * rcpW);
|
||||
int32_t posV = (int32_t)(blockPosY.V * rcpW);
|
||||
|
||||
fixed_t lightpos = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask);
|
||||
|
||||
blockPosX.W += gradientX.W * 8;
|
||||
blockPosX.U += gradientX.U * 8;
|
||||
blockPosX.V += gradientX.V * 8;
|
||||
ScreenTriangleStepVariables blockPosX = blockPosY;
|
||||
blockPosX.W += gradientX.W;
|
||||
blockPosX.U += gradientX.U;
|
||||
blockPosX.V += gradientX.V;
|
||||
|
||||
rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t nextU = (int32_t)(blockPosX.U * rcpW);
|
||||
|
@ -677,20 +637,6 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
static float FindGradientX(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2)
|
||||
{
|
||||
float top = (c1 - c2) * (y0 - y2) - (c0 - c2) * (y1 - y2);
|
||||
float bottom = (x1 - x2) * (y0 - y2) - (x0 - x2) * (y1 - y2);
|
||||
return top / bottom;
|
||||
}
|
||||
|
||||
static float FindGradientY(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2)
|
||||
{
|
||||
float top = (c1 - c2) * (x0 - x2) - (c0 - c2) * (x1 - x2);
|
||||
float bottom = (x0 - x2) * (y1 - y2) - (x1 - x2) * (y0 - y2);
|
||||
return top / bottom;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BlendT, typename SamplerT>
|
||||
|
|
|
@ -209,17 +209,10 @@ template<typename BlendT, typename SamplerT>
|
|||
class TriScreenDrawer8
|
||||
{
|
||||
public:
|
||||
static void Execute(const TriDrawTriangleArgs *args, WorkerThreadData *thread)
|
||||
static void Execute(int destX, int destY, uint32_t mask0, uint32_t mask1, const TriDrawTriangleArgs *args)
|
||||
{
|
||||
using namespace TriScreenDrawerModes;
|
||||
|
||||
int numSpans = thread->NumFullSpans;
|
||||
auto fullSpans = thread->FullSpans;
|
||||
int numBlocks = thread->NumPartialBlocks;
|
||||
auto partialBlocks = thread->PartialBlocks;
|
||||
int startX = thread->StartX;
|
||||
int startY = thread->StartY;
|
||||
|
||||
bool is_fixed_light = args->uniforms->FixedLight();
|
||||
uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff;
|
||||
auto colormaps = args->uniforms->BaseColormap();
|
||||
|
@ -228,24 +221,20 @@ public:
|
|||
|
||||
// Calculate gradients
|
||||
const TriVertex &v1 = *args->v1;
|
||||
const TriVertex &v2 = *args->v2;
|
||||
const TriVertex &v3 = *args->v3;
|
||||
ScreenTriangleStepVariables gradientX;
|
||||
ScreenTriangleStepVariables gradientY;
|
||||
ScreenTriangleStepVariables start;
|
||||
gradientX.W = FindGradientX(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.w, v2.w, v3.w);
|
||||
gradientY.W = FindGradientY(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.w, v2.w, v3.w);
|
||||
gradientX.U = FindGradientX(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.u * v1.w, v2.u * v2.w, v3.u * v3.w);
|
||||
gradientY.U = FindGradientY(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.u * v1.w, v2.u * v2.w, v3.u * v3.w);
|
||||
gradientX.V = FindGradientX(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.v * v1.w, v2.v * v2.w, v3.v * v3.w);
|
||||
gradientY.V = FindGradientY(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.v * v1.w, v2.v * v2.w, v3.v * v3.w);
|
||||
start.W = v1.w + gradientX.W * (startX - v1.x) + gradientY.W * (startY - v1.y);
|
||||
start.U = v1.u * v1.w + gradientX.U * (startX - v1.x) + gradientY.U * (startY - v1.y);
|
||||
start.V = v1.v * v1.w + gradientX.V * (startX - v1.x) + gradientY.V * (startY - v1.y);
|
||||
ScreenTriangleStepVariables gradientX = args->gradientX;
|
||||
ScreenTriangleStepVariables gradientY = args->gradientY;
|
||||
ScreenTriangleStepVariables blockPosY;
|
||||
blockPosY.W = v1.w + gradientX.W * (destX - v1.x) + gradientY.W * (destY - v1.y);
|
||||
blockPosY.U = v1.u * v1.w + gradientX.U * (destX - v1.x) + gradientY.U * (destY - v1.y);
|
||||
blockPosY.V = v1.v * v1.w + gradientX.V * (destX - v1.x) + gradientY.V * (destY - v1.y);
|
||||
gradientX.W *= 8.0f;
|
||||
gradientX.U *= 8.0f;
|
||||
gradientX.V *= 8.0f;
|
||||
|
||||
// Output
|
||||
uint8_t * RESTRICT destOrg = args->dest;
|
||||
int pitch = args->pitch;
|
||||
uint8_t *dest = destOrg + destX + destY * pitch;
|
||||
|
||||
// Light
|
||||
uint32_t light = args->uniforms->Light();
|
||||
|
@ -260,57 +249,42 @@ public:
|
|||
uint32_t texWidth = args->uniforms->TextureWidth();
|
||||
uint32_t texHeight = args->uniforms->TextureHeight();
|
||||
|
||||
for (int i = 0; i < numSpans; i++)
|
||||
if (mask0 == 0xffffffff && mask1 == 0xffffffff)
|
||||
{
|
||||
const auto &span = fullSpans[i];
|
||||
|
||||
uint8_t *dest = destOrg + span.X + span.Y * pitch;
|
||||
int width = span.Length;
|
||||
int height = 8;
|
||||
|
||||
ScreenTriangleStepVariables blockPosY;
|
||||
blockPosY.W = start.W + gradientX.W * (span.X - startX) + gradientY.W * (span.Y - startY);
|
||||
blockPosY.U = start.U + gradientX.U * (span.X - startX) + gradientY.U * (span.Y - startY);
|
||||
blockPosY.V = start.V + gradientX.V * (span.X - startX) + gradientY.V * (span.Y - startY);
|
||||
|
||||
for (int y = 0; y < height; y++)
|
||||
for (int y = 0; y < 8; y++)
|
||||
{
|
||||
ScreenTriangleStepVariables blockPosX = blockPosY;
|
||||
|
||||
float rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t posU = (int32_t)(blockPosX.U * rcpW);
|
||||
int32_t posV = (int32_t)(blockPosX.V * rcpW);
|
||||
float rcpW = 0x01000000 / blockPosY.W;
|
||||
int32_t posU = (int32_t)(blockPosY.U * rcpW);
|
||||
int32_t posV = (int32_t)(blockPosY.V * rcpW);
|
||||
|
||||
fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask);
|
||||
|
||||
for (int x = 0; x < width; x++)
|
||||
ScreenTriangleStepVariables blockPosX = blockPosY;
|
||||
blockPosX.W += gradientX.W;
|
||||
blockPosX.U += gradientX.U;
|
||||
blockPosX.V += gradientX.V;
|
||||
|
||||
rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t nextU = (int32_t)(blockPosX.U * rcpW);
|
||||
int32_t nextV = (int32_t)(blockPosX.V * rcpW);
|
||||
int32_t stepU = (nextU - posU) / 8;
|
||||
int32_t stepV = (nextV - posV) / 8;
|
||||
|
||||
fixed_t lightnext = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosX.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
fixed_t lightstep = (lightnext - lightpos) / 8;
|
||||
lightstep = lightstep & lightmask;
|
||||
|
||||
for (int ix = 0; ix < 8; ix++)
|
||||
{
|
||||
blockPosX.W += gradientX.W * 8;
|
||||
blockPosX.U += gradientX.U * 8;
|
||||
blockPosX.V += gradientX.V * 8;
|
||||
|
||||
rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t nextU = (int32_t)(blockPosX.U * rcpW);
|
||||
int32_t nextV = (int32_t)(blockPosX.V * rcpW);
|
||||
int32_t stepU = (nextU - posU) / 8;
|
||||
int32_t stepV = (nextV - posV) / 8;
|
||||
|
||||
fixed_t lightnext = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosX.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
fixed_t lightstep = (lightnext - lightpos) / 8;
|
||||
lightstep = lightstep & lightmask;
|
||||
|
||||
for (int ix = 0; ix < 8; ix++)
|
||||
{
|
||||
int lightshade = lightpos >> 8;
|
||||
uint8_t bgcolor = dest[x * 8 + ix];
|
||||
uint8_t fgcolor = Sample8<SamplerT>(posU, posV, texPixels, texWidth, texHeight, color, translation);
|
||||
uint32_t fgshade = SampleShade8<SamplerT>(posU, posV, texPixels, texWidth, texHeight);
|
||||
dest[x * 8 + ix] = ShadeAndBlend8<BlendT>(fgcolor, bgcolor, fgshade, lightshade, colormaps, srcalpha, destalpha);
|
||||
posU += stepU;
|
||||
posV += stepV;
|
||||
lightpos += lightstep;
|
||||
}
|
||||
int lightshade = lightpos >> 8;
|
||||
uint8_t bgcolor = dest[ix];
|
||||
uint8_t fgcolor = Sample8<SamplerT>(posU, posV, texPixels, texWidth, texHeight, color, translation);
|
||||
uint32_t fgshade = SampleShade8<SamplerT>(posU, posV, texPixels, texWidth, texHeight);
|
||||
dest[ix] = ShadeAndBlend8<BlendT>(fgcolor, bgcolor, fgshade, lightshade, colormaps, srcalpha, destalpha);
|
||||
posU += stepU;
|
||||
posV += stepV;
|
||||
lightpos += lightstep;
|
||||
}
|
||||
|
||||
blockPosY.W += gradientY.W;
|
||||
|
@ -320,35 +294,22 @@ public:
|
|||
dest += pitch;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < numBlocks; i++)
|
||||
else
|
||||
{
|
||||
const auto &block = partialBlocks[i];
|
||||
|
||||
ScreenTriangleStepVariables blockPosY;
|
||||
blockPosY.W = start.W + gradientX.W * (block.X - startX) + gradientY.W * (block.Y - startY);
|
||||
blockPosY.U = start.U + gradientX.U * (block.X - startX) + gradientY.U * (block.Y - startY);
|
||||
blockPosY.V = start.V + gradientX.V * (block.X - startX) + gradientY.V * (block.Y - startY);
|
||||
|
||||
uint8_t *dest = destOrg + block.X + block.Y * pitch;
|
||||
uint32_t mask0 = block.Mask0;
|
||||
uint32_t mask1 = block.Mask1;
|
||||
|
||||
// mask0 loop:
|
||||
for (int y = 0; y < 4; y++)
|
||||
{
|
||||
ScreenTriangleStepVariables blockPosX = blockPosY;
|
||||
|
||||
float rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t posU = (int32_t)(blockPosX.U * rcpW);
|
||||
int32_t posV = (int32_t)(blockPosX.V * rcpW);
|
||||
float rcpW = 0x01000000 / blockPosY.W;
|
||||
int32_t posU = (int32_t)(blockPosY.U * rcpW);
|
||||
int32_t posV = (int32_t)(blockPosY.V * rcpW);
|
||||
|
||||
fixed_t lightpos = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask);
|
||||
|
||||
blockPosX.W += gradientX.W * 8;
|
||||
blockPosX.U += gradientX.U * 8;
|
||||
blockPosX.V += gradientX.V * 8;
|
||||
ScreenTriangleStepVariables blockPosX = blockPosY;
|
||||
blockPosX.W += gradientX.W;
|
||||
blockPosX.U += gradientX.U;
|
||||
blockPosX.V += gradientX.V;
|
||||
|
||||
rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t nextU = (int32_t)(blockPosX.U * rcpW);
|
||||
|
@ -388,18 +349,17 @@ public:
|
|||
// mask1 loop:
|
||||
for (int y = 0; y < 4; y++)
|
||||
{
|
||||
ScreenTriangleStepVariables blockPosX = blockPosY;
|
||||
|
||||
float rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t posU = (int32_t)(blockPosX.U * rcpW);
|
||||
int32_t posV = (int32_t)(blockPosX.V * rcpW);
|
||||
float rcpW = 0x01000000 / blockPosY.W;
|
||||
int32_t posU = (int32_t)(blockPosY.U * rcpW);
|
||||
int32_t posV = (int32_t)(blockPosY.V * rcpW);
|
||||
|
||||
fixed_t lightpos = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask);
|
||||
|
||||
blockPosX.W += gradientX.W * 8;
|
||||
blockPosX.U += gradientX.U * 8;
|
||||
blockPosX.V += gradientX.V * 8;
|
||||
ScreenTriangleStepVariables blockPosX = blockPosY;
|
||||
blockPosX.W += gradientX.W;
|
||||
blockPosX.U += gradientX.U;
|
||||
blockPosX.V += gradientX.V;
|
||||
|
||||
rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t nextU = (int32_t)(blockPosX.U * rcpW);
|
||||
|
@ -437,21 +397,6 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static float FindGradientX(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2)
|
||||
{
|
||||
float top = (c1 - c2) * (y0 - y2) - (c0 - c2) * (y1 - y2);
|
||||
float bottom = (x1 - x2) * (y0 - y2) - (x0 - x2) * (y1 - y2);
|
||||
return top / bottom;
|
||||
}
|
||||
|
||||
static float FindGradientY(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2)
|
||||
{
|
||||
float top = (c1 - c2) * (x0 - x2) - (c0 - c2) * (x1 - x2);
|
||||
float bottom = (x0 - x2) * (y1 - y2) - (x1 - x2) * (y0 - y2);
|
||||
return top / bottom;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BlendT, typename SamplerT>
|
||||
|
|
|
@ -38,8 +38,6 @@
|
|||
#include "swrenderer/drawers/r_draw_rgba.h"
|
||||
#include "screen_triangle.h"
|
||||
|
||||
CVAR(Bool, r_debug_trisetup, false, 0);
|
||||
|
||||
int PolyTriangleDrawer::viewport_x;
|
||||
int PolyTriangleDrawer::viewport_y;
|
||||
int PolyTriangleDrawer::viewport_width;
|
||||
|
@ -90,33 +88,13 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, WorkerThreadD
|
|||
if (drawargs.VertexCount() < 3)
|
||||
return;
|
||||
|
||||
PolyDrawFuncPtr drawfuncs[4];
|
||||
int num_drawfuncs = 0;
|
||||
|
||||
drawfuncs[num_drawfuncs++] = drawargs.SubsectorTest() ? &ScreenTriangle::SetupSubsector : &ScreenTriangle::SetupNormal;
|
||||
|
||||
if (!r_debug_trisetup) // For profiling how much time is spent in setup vs drawal
|
||||
{
|
||||
int bmode = (int)drawargs.BlendMode();
|
||||
|
||||
if (drawargs.WriteColor())
|
||||
drawfuncs[num_drawfuncs++] = dest_bgra ? ScreenTriangle::TriDrawers32[bmode] : ScreenTriangle::TriDrawers8[bmode];
|
||||
}
|
||||
|
||||
if (drawargs.WriteStencil())
|
||||
drawfuncs[num_drawfuncs++] = &ScreenTriangle::StencilWrite;
|
||||
|
||||
if (drawargs.WriteSubsector())
|
||||
drawfuncs[num_drawfuncs++] = &ScreenTriangle::SubsectorWrite;
|
||||
|
||||
TriDrawTriangleArgs args;
|
||||
args.dest = dest;
|
||||
args.pitch = dest_pitch;
|
||||
args.clipleft = 0;
|
||||
args.clipright = dest_width;
|
||||
args.cliptop = 0;
|
||||
args.clipbottom = dest_height;
|
||||
args.uniforms = &drawargs;
|
||||
args.destBgra = dest_bgra;
|
||||
args.stencilPitch = PolyStencilBuffer::Instance()->BlockWidth();
|
||||
args.stencilValues = PolyStencilBuffer::Instance()->Values();
|
||||
args.stencilMasks = PolyStencilBuffer::Instance()->Masks();
|
||||
|
@ -133,7 +111,7 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, WorkerThreadD
|
|||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
vert[j] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++));
|
||||
draw_shaded_triangle(vert, ccw, &args, thread, drawfuncs, num_drawfuncs);
|
||||
draw_shaded_triangle(vert, ccw, &args, thread);
|
||||
}
|
||||
}
|
||||
else if (drawargs.DrawMode() == PolyDrawMode::TriangleFan)
|
||||
|
@ -143,7 +121,7 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, WorkerThreadD
|
|||
for (int i = 2; i < vcount; i++)
|
||||
{
|
||||
vert[2] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++));
|
||||
draw_shaded_triangle(vert, ccw, &args, thread, drawfuncs, num_drawfuncs);
|
||||
draw_shaded_triangle(vert, ccw, &args, thread);
|
||||
vert[1] = vert[2];
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +132,7 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, WorkerThreadD
|
|||
for (int i = 2; i < vcount; i++)
|
||||
{
|
||||
vert[2] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++));
|
||||
draw_shaded_triangle(vert, ccw, &args, thread, drawfuncs, num_drawfuncs);
|
||||
draw_shaded_triangle(vert, ccw, &args, thread);
|
||||
vert[0] = vert[1];
|
||||
vert[1] = vert[2];
|
||||
ccw = !ccw;
|
||||
|
@ -173,7 +151,7 @@ ShadedTriVertex PolyTriangleDrawer::shade_vertex(const TriMatrix &objectToClip,
|
|||
return sv;
|
||||
}
|
||||
|
||||
void PolyTriangleDrawer::draw_shaded_triangle(const ShadedTriVertex *vert, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread, PolyDrawFuncPtr *drawfuncs, int num_drawfuncs)
|
||||
void PolyTriangleDrawer::draw_shaded_triangle(const ShadedTriVertex *vert, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread)
|
||||
{
|
||||
// Cull, clip and generate additional vertices as needed
|
||||
TriVertex clippedvert[max_additional_vertices];
|
||||
|
@ -249,9 +227,9 @@ void PolyTriangleDrawer::draw_shaded_triangle(const ShadedTriVertex *vert, bool
|
|||
args->v1 = &clippedvert[numclipvert - 1];
|
||||
args->v2 = &clippedvert[i - 1];
|
||||
args->v3 = &clippedvert[i - 2];
|
||||
args->CalculateGradients();
|
||||
|
||||
for (int j = 0; j < num_drawfuncs; j++)
|
||||
drawfuncs[j](args, thread);
|
||||
ScreenTriangle::Draw(args, thread);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -261,9 +239,9 @@ void PolyTriangleDrawer::draw_shaded_triangle(const ShadedTriVertex *vert, bool
|
|||
args->v1 = &clippedvert[0];
|
||||
args->v2 = &clippedvert[i - 1];
|
||||
args->v3 = &clippedvert[i];
|
||||
args->CalculateGradients();
|
||||
|
||||
for (int j = 0; j < num_drawfuncs; j++)
|
||||
drawfuncs[j](args, thread);
|
||||
ScreenTriangle::Draw(args, thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -444,8 +422,6 @@ void DrawPolyTrianglesCommand::Execute(DrawerThread *thread)
|
|||
WorkerThreadData thread_data;
|
||||
thread_data.core = thread->core;
|
||||
thread_data.num_cores = thread->num_cores;
|
||||
thread_data.FullSpans = thread->FullSpansBuffer.data();
|
||||
thread_data.PartialBlocks = thread->PartialBlocksBuffer.data();
|
||||
|
||||
PolyTriangleDrawer::draw_arrays(args, &thread_data);
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
private:
|
||||
static ShadedTriVertex shade_vertex(const TriMatrix &objectToClip, const float *clipPlane, const TriVertex &v);
|
||||
static void draw_arrays(const PolyDrawArgs &args, WorkerThreadData *thread);
|
||||
static void draw_shaded_triangle(const ShadedTriVertex *vertices, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread, PolyDrawFuncPtr *drawfuncs, int num_drawfuncs);
|
||||
static void draw_shaded_triangle(const ShadedTriVertex *vertices, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread);
|
||||
|
||||
static int clipedge(const ShadedTriVertex *verts, TriVertex *clippedvert);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -28,34 +28,10 @@
|
|||
class FString;
|
||||
class PolyDrawArgs;
|
||||
|
||||
struct TriFullSpan
|
||||
{
|
||||
uint16_t X;
|
||||
uint16_t Y;
|
||||
uint32_t Length;
|
||||
};
|
||||
|
||||
struct TriPartialBlock
|
||||
{
|
||||
uint16_t X;
|
||||
uint16_t Y;
|
||||
uint32_t Mask0;
|
||||
uint32_t Mask1;
|
||||
};
|
||||
|
||||
struct WorkerThreadData
|
||||
{
|
||||
int32_t core;
|
||||
int32_t num_cores;
|
||||
uint32_t *temp;
|
||||
|
||||
// Triangle working data:
|
||||
TriFullSpan *FullSpans;
|
||||
TriPartialBlock *PartialBlocks;
|
||||
uint32_t NumFullSpans;
|
||||
uint32_t NumPartialBlocks;
|
||||
int32_t StartX;
|
||||
int32_t StartY;
|
||||
};
|
||||
|
||||
struct TriVertex
|
||||
|
@ -67,6 +43,11 @@ struct TriVertex
|
|||
float u, v;
|
||||
};
|
||||
|
||||
struct ScreenTriangleStepVariables
|
||||
{
|
||||
float W, U, V;
|
||||
};
|
||||
|
||||
struct TriDrawTriangleArgs
|
||||
{
|
||||
uint8_t *dest;
|
||||
|
@ -74,15 +55,41 @@ struct TriDrawTriangleArgs
|
|||
TriVertex *v1;
|
||||
TriVertex *v2;
|
||||
TriVertex *v3;
|
||||
int32_t clipleft;
|
||||
int32_t clipright;
|
||||
int32_t cliptop;
|
||||
int32_t clipbottom;
|
||||
uint8_t *stencilValues;
|
||||
uint32_t *stencilMasks;
|
||||
int32_t stencilPitch;
|
||||
uint32_t *subsectorGBuffer;
|
||||
const PolyDrawArgs *uniforms;
|
||||
bool destBgra;
|
||||
ScreenTriangleStepVariables gradientX;
|
||||
ScreenTriangleStepVariables gradientY;
|
||||
|
||||
void CalculateGradients()
|
||||
{
|
||||
gradientX.W = FindGradientX(v1->x, v1->y, v2->x, v2->y, v3->x, v3->y, v1->w, v2->w, v3->w);
|
||||
gradientY.W = FindGradientY(v1->x, v1->y, v2->x, v2->y, v3->x, v3->y, v1->w, v2->w, v3->w);
|
||||
gradientX.U = FindGradientX(v1->x, v1->y, v2->x, v2->y, v3->x, v3->y, v1->u * v1->w, v2->u * v2->w, v3->u * v3->w);
|
||||
gradientY.U = FindGradientY(v1->x, v1->y, v2->x, v2->y, v3->x, v3->y, v1->u * v1->w, v2->u * v2->w, v3->u * v3->w);
|
||||
gradientX.V = FindGradientX(v1->x, v1->y, v2->x, v2->y, v3->x, v3->y, v1->v * v1->w, v2->v * v2->w, v3->v * v3->w);
|
||||
gradientY.V = FindGradientY(v1->x, v1->y, v2->x, v2->y, v3->x, v3->y, v1->v * v1->w, v2->v * v2->w, v3->v * v3->w);
|
||||
}
|
||||
|
||||
private:
|
||||
static float FindGradientX(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2)
|
||||
{
|
||||
float top = (c1 - c2) * (y0 - y2) - (c0 - c2) * (y1 - y2);
|
||||
float bottom = (x1 - x2) * (y0 - y2) - (x0 - x2) * (y1 - y2);
|
||||
return top / bottom;
|
||||
}
|
||||
|
||||
static float FindGradientY(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2)
|
||||
{
|
||||
float top = (c1 - c2) * (x0 - x2) - (c0 - c2) * (x1 - x2);
|
||||
float bottom = (x0 - x2) * (y1 - y2) - (x1 - x2) * (y0 - y2);
|
||||
return top / bottom;
|
||||
}
|
||||
};
|
||||
|
||||
class RectDrawArgs;
|
||||
|
@ -116,22 +123,14 @@ enum class TriBlendMode
|
|||
class ScreenTriangle
|
||||
{
|
||||
public:
|
||||
static void SetupNormal(const TriDrawTriangleArgs *args, WorkerThreadData *thread);
|
||||
static void SetupSubsector(const TriDrawTriangleArgs *args, WorkerThreadData *thread);
|
||||
static void StencilWrite(const TriDrawTriangleArgs *args, WorkerThreadData *thread);
|
||||
static void SubsectorWrite(const TriDrawTriangleArgs *args, WorkerThreadData *thread);
|
||||
static void Draw(const TriDrawTriangleArgs *args, WorkerThreadData *thread);
|
||||
|
||||
static void(*TriDrawers8[])(const TriDrawTriangleArgs *, WorkerThreadData *);
|
||||
static void(*TriDrawers32[])(const TriDrawTriangleArgs *, WorkerThreadData *);
|
||||
static void(*TriDrawers8[])(int, int, uint32_t, uint32_t, const TriDrawTriangleArgs *);
|
||||
static void(*TriDrawers32[])(int, int, uint32_t, uint32_t, const TriDrawTriangleArgs *);
|
||||
static void(*RectDrawers8[])(const void *, int, int, int, const RectDrawArgs *, WorkerThreadData *);
|
||||
static void(*RectDrawers32[])(const void *, int, int, int, const RectDrawArgs *, WorkerThreadData *);
|
||||
};
|
||||
|
||||
struct ScreenTriangleStepVariables
|
||||
{
|
||||
float W, U, V;
|
||||
};
|
||||
|
||||
namespace TriScreenDrawerModes
|
||||
{
|
||||
enum class BlendModes { Opaque, Masked, AddClamp, SubClamp, RevSubClamp, AddSrcColorOneMinusSrcColor, Shaded, AddClampShaded };
|
||||
|
|
|
@ -1146,7 +1146,7 @@ void CocoaFrameBuffer::Flip()
|
|||
|
||||
SDLGLFB::SDLGLFB(void*, const int width, const int height, int, int, const bool fullscreen, bool bgra)
|
||||
: DFrameBuffer(width, height, bgra)
|
||||
, m_lock(-1)
|
||||
, m_lock(0)
|
||||
, m_isUpdatePending(false)
|
||||
{
|
||||
CGGammaValue gammaTable[GAMMA_TABLE_SIZE];
|
||||
|
|
|
@ -139,6 +139,7 @@ void VMFunctionBuilder::MakeFunction(VMScriptFunction *func)
|
|||
func->NumRegA = Registers[REGT_POINTER].MostUsed;
|
||||
func->NumRegS = Registers[REGT_STRING].MostUsed;
|
||||
func->MaxParam = MaxParam;
|
||||
func->StackSize = VMFrame::FrameSize(func->NumRegD, func->NumRegF, func->NumRegS, func->NumRegA, func->MaxParam, func->ExtraSpace);
|
||||
|
||||
// Technically, there's no reason why we can't end the function with
|
||||
// entries on the parameter stack, but it means the caller probably
|
||||
|
|
|
@ -716,6 +716,7 @@ public:
|
|||
int ExtraSpace;
|
||||
int CodeSize; // Size of code in instructions (not bytes)
|
||||
unsigned LineInfoCount;
|
||||
unsigned StackSize;
|
||||
VM_UBYTE NumRegD;
|
||||
VM_UBYTE NumRegF;
|
||||
VM_UBYTE NumRegS;
|
||||
|
|
|
@ -273,9 +273,7 @@ VMFrameStack::~VMFrameStack()
|
|||
|
||||
VMFrame *VMFrameStack::AllocFrame(VMScriptFunction *func)
|
||||
{
|
||||
int size = VMFrame::FrameSize(func->NumRegD, func->NumRegF, func->NumRegS, func->NumRegA,
|
||||
func->MaxParam, func->ExtraSpace);
|
||||
VMFrame *frame = Alloc(size);
|
||||
VMFrame *frame = Alloc(func->StackSize);
|
||||
frame->Func = func;
|
||||
frame->NumRegD = func->NumRegD;
|
||||
frame->NumRegF = func->NumRegF;
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "r_draw.h"
|
||||
#include "polyrenderer/drawers/screen_triangle.h"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
@ -37,12 +36,6 @@ EXTERN_CVAR(Bool, r_multithreaded)
|
|||
class DrawerThread
|
||||
{
|
||||
public:
|
||||
DrawerThread()
|
||||
{
|
||||
FullSpansBuffer.resize(MAXWIDTH / 8 * (MAXHEIGHT / 8));
|
||||
PartialBlocksBuffer.resize(MAXWIDTH / 8 * (MAXHEIGHT / 8));
|
||||
}
|
||||
|
||||
std::thread thread;
|
||||
size_t current_queue = 0;
|
||||
|
||||
|
@ -55,10 +48,6 @@ public:
|
|||
// Working buffer used by the tilted (sloped) span drawer
|
||||
const uint8_t *tiltlighting[MAXWIDTH];
|
||||
|
||||
// Working buffer used by the triangler drawer
|
||||
std::vector<TriFullSpan> FullSpansBuffer;
|
||||
std::vector<TriPartialBlock> PartialBlocksBuffer;
|
||||
|
||||
// Checks if a line is rendered by this thread
|
||||
bool line_skipped_by_thread(int line)
|
||||
{
|
||||
|
|
|
@ -1122,6 +1122,7 @@ void DFrameBuffer::SetBlendingRect (int x1, int y1, int x2, int y2)
|
|||
|
||||
bool DFrameBuffer::Begin2D (bool copy3d)
|
||||
{
|
||||
isIn2D = true;
|
||||
ClearClipRect();
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -413,9 +413,10 @@ public:
|
|||
// avoid copying the software buffer to the screen.
|
||||
// Returns true if hardware-accelerated 2D has been entered, false if not.
|
||||
virtual bool Begin2D(bool copy3d);
|
||||
void End2D() { isIn2D = false; }
|
||||
|
||||
// Returns true if Begin2D has been called and 2D drawing is now active
|
||||
virtual bool HasBegun2D() { return IsLocked(); }
|
||||
bool HasBegun2D() { return isIn2D; }
|
||||
|
||||
// DrawTexture calls after Begin2D use native textures.
|
||||
|
||||
|
@ -463,6 +464,7 @@ protected:
|
|||
|
||||
private:
|
||||
uint32_t LastMS, LastSec, FrameCount, LastCount, LastTic;
|
||||
bool isIn2D = false;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2557,7 +2557,7 @@ bool D3DPal::Update()
|
|||
|
||||
bool D3DFB::Begin2D(bool copy3d)
|
||||
{
|
||||
ClearClipRect();
|
||||
Super::Begin2D(copy3d);
|
||||
if (!Accel2D)
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -105,7 +105,6 @@ public:
|
|||
D3DFB (UINT adapter, int width, int height, bool bgra, bool fullscreen);
|
||||
~D3DFB ();
|
||||
|
||||
bool HasBegun2D() override { return In2D || IsLocked(); }
|
||||
bool IsValid ();
|
||||
bool Lock (bool buffered);
|
||||
void Unlock ();
|
||||
|
|
|
@ -48,10 +48,8 @@ class DoomStatusBar : BaseStatusBar
|
|||
DrawImage("STTPRCNT", (90, 171), DI_ITEM_OFFSETS);
|
||||
DrawImage("STTPRCNT", (221, 171), DI_ITEM_OFFSETS);
|
||||
|
||||
Inventory a1, a2;
|
||||
int amt1;
|
||||
[a1, a2, amt1] = GetCurrentAmmo();
|
||||
DrawString(mHUDFont, FormatNumber(amt1, 3), (44, 171), DI_TEXT_ALIGN_RIGHT|DI_NOSHADOW);
|
||||
Inventory a1 = GetCurrentAmmo();
|
||||
if (a1 != null) DrawString(mHUDFont, FormatNumber(a1.Amount, 3), (44, 171), DI_TEXT_ALIGN_RIGHT|DI_NOSHADOW);
|
||||
DrawString(mHUDFont, FormatNumber(CPlayer.health, 3), (90, 171), DI_TEXT_ALIGN_RIGHT|DI_NOSHADOW);
|
||||
DrawString(mHUDFont, FormatNumber(GetArmorAmount(), 3), (221, 171), DI_TEXT_ALIGN_RIGHT|DI_NOSHADOW);
|
||||
|
||||
|
@ -76,7 +74,7 @@ class DoomStatusBar : BaseStatusBar
|
|||
else image = "";
|
||||
DrawImage(image, (239, 191), DI_ITEM_OFFSETS);
|
||||
|
||||
int maxamt;
|
||||
int amt1, maxamt;
|
||||
[amt1, maxamt] = GetAmount("Clip");
|
||||
DrawString(mIndexFont, FormatNumber(amt1, 3), (288, 173), DI_TEXT_ALIGN_RIGHT);
|
||||
DrawString(mIndexFont, FormatNumber(maxamt, 3), (314, 173), DI_TEXT_ALIGN_RIGHT);
|
||||
|
|
|
@ -104,13 +104,24 @@ class HexenStatusBar : BaseStatusBar
|
|||
protected void DrawMainBar (double TicFrac)
|
||||
{
|
||||
DrawImage("H2BAR", (0, 134), DI_ITEM_OFFSETS);
|
||||
|
||||
String Gem;
|
||||
if (CPlayer.mo is "ClericPlayer") Gem = "LIFEGMC2";
|
||||
else if (CPlayer.mo is "MagePlayer") Gem = "LIFEGMM2";
|
||||
else Gem = "LIFEGMF2";
|
||||
|
||||
int inthealth = mHealthInterpolator2.GetValue();
|
||||
DrawGem("CHAIN", "LIFEGMF2", inthealth, CPlayer.mo.GetMaxHealth(true), (30, 193), -23, 49, 15, (multiplayer? DI_TRANSLATABLE : 0) | DI_ITEM_LEFT_TOP);
|
||||
|
||||
DrawImage("LFEDGE", (0, 192), DI_ITEM_OFFSETS);
|
||||
DrawImage("RTEDGE", (277, 192), DI_ITEM_OFFSETS);
|
||||
|
||||
if (!automapactive)
|
||||
{
|
||||
if (isInventoryBarVisible())
|
||||
{
|
||||
DrawImage("INVBAR", (38, 162), DI_ITEM_OFFSETS);
|
||||
DrawInventoryBar(diparms_sbar, (52, 163), 7, DI_ITEM_LEFT_TOP, HX_SHADOW);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -229,7 +240,6 @@ class HexenStatusBar : BaseStatusBar
|
|||
}
|
||||
else // automap
|
||||
{
|
||||
DrawImage("H2BAR", (0, 134), DI_ITEM_OFFSETS);
|
||||
DrawImage("KEYBAR", (38, 162), DI_ITEM_OFFSETS);
|
||||
int cnt = 0;
|
||||
Vector2 keypos = (46, 164);
|
||||
|
@ -247,17 +257,6 @@ class HexenStatusBar : BaseStatusBar
|
|||
DrawHexenArmor(HEXENARMOR_HELM, "ARMSLOT3", (212, 164), DI_ITEM_OFFSETS);
|
||||
DrawHexenArmor(HEXENARMOR_AMULET, "ARMSLOT4", (243, 164), DI_ITEM_OFFSETS);
|
||||
}
|
||||
|
||||
String Gem;
|
||||
if (CPlayer.mo is "ClericPlayer") Gem = "LIFEGMC2";
|
||||
else if (CPlayer.mo is "MagePlayer") Gem = "LIFEGMM2";
|
||||
else Gem = "LIFEGMF2";
|
||||
|
||||
int inthealth = mHealthInterpolator2.GetValue();
|
||||
DrawGem("CHAIN", "LIFEGMF2", inthealth, CPlayer.mo.GetMaxHealth(true), (30, 193), -23, 49, 15, (multiplayer? DI_TRANSLATABLE : 0) | DI_ITEM_LEFT_TOP);
|
||||
|
||||
DrawImage("LFEDGE", (0, 193), DI_ITEM_OFFSETS);
|
||||
DrawImage("RTEDGE", (277, 193), DI_ITEM_OFFSETS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -452,7 +452,7 @@ class BaseStatusBar native ui
|
|||
int, int GetAmount(class<Inventory> item)
|
||||
{
|
||||
let it = CPlayer.mo.FindInventory(item);
|
||||
int ret1 = it? it.Amount : GetDefaultByType(item).Amount;
|
||||
int ret1 = it? it.Amount : 0;
|
||||
int ret2 = it? it.MaxAmount : GetDefaultByType(item).MaxAmount;
|
||||
return ret1, ret2;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue