mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-29 07:22:05 +00:00
Queue a full wall as one draw command
This commit is contained in:
parent
310459b490
commit
62b2039a75
13 changed files with 599 additions and 448 deletions
|
@ -51,6 +51,7 @@
|
|||
#include "r_draw_pal.h"
|
||||
#include "r_thread.h"
|
||||
#include "swrenderer/scene/r_light.h"
|
||||
#include "playsim/a_dynlight.h"
|
||||
|
||||
CVAR(Bool, r_dynlights, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
CVAR(Bool, r_fuzzscale, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
|
@ -216,34 +217,343 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
|
||||
class DepthColumnCommand : public DrawerCommand
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DrawWallCommand::DrawWallCommand(const WallDrawerArgs& args) : wallargs(args)
|
||||
{
|
||||
public:
|
||||
DepthColumnCommand(const WallDrawerArgs &args, float idepth) : idepth(idepth)
|
||||
}
|
||||
|
||||
void DrawWallCommand::Execute(DrawerThread* thread)
|
||||
{
|
||||
WallColumnDrawerArgs drawerargs(wallargs);
|
||||
|
||||
bool fixed = wallargs.fixedlight;
|
||||
|
||||
bool haslights = r_dynlights && wallargs.lightlist;
|
||||
if (haslights)
|
||||
{
|
||||
auto rendertarget = args.Viewport()->RenderTarget;
|
||||
if (rendertarget->IsBgra())
|
||||
{
|
||||
uint32_t *destorg = (uint32_t*)rendertarget->GetPixels();
|
||||
destorg += viewwindowx + viewwindowy * rendertarget->GetPitch();
|
||||
uint32_t *dest = (uint32_t*)args.Dest();
|
||||
int offset = (int)(ptrdiff_t)(dest - destorg);
|
||||
x = offset % rendertarget->GetPitch();
|
||||
y = offset / rendertarget->GetPitch();
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *destorg = rendertarget->GetPixels();
|
||||
destorg += viewwindowx + viewwindowy * rendertarget->GetPitch();
|
||||
uint8_t *dest = (uint8_t*)args.Dest();
|
||||
int offset = (int)(ptrdiff_t)(dest - destorg);
|
||||
x = offset % rendertarget->GetPitch();
|
||||
y = offset / rendertarget->GetPitch();
|
||||
}
|
||||
count = args.Count();
|
||||
float dx = wallargs.WallC.tright.X - wallargs.WallC.tleft.X;
|
||||
float dy = wallargs.WallC.tright.Y - wallargs.WallC.tleft.Y;
|
||||
float length = sqrt(dx * dx + dy * dy);
|
||||
drawerargs.dc_normal.X = dy / length;
|
||||
drawerargs.dc_normal.Y = -dx / length;
|
||||
drawerargs.dc_normal.Z = 0.0f;
|
||||
}
|
||||
|
||||
DepthColumnCommand(const SkyDrawerArgs &args, float idepth) : idepth(idepth)
|
||||
drawerargs.SetTextureFracBits(wallargs.fracbits);
|
||||
|
||||
float curlight = wallargs.lightpos;
|
||||
float lightstep = wallargs.lightstep;
|
||||
int shade = wallargs.mShade;
|
||||
|
||||
float upos = wallargs.texcoords.upos, ustepX = wallargs.texcoords.ustepX, ustepY = wallargs.texcoords.ustepY;
|
||||
float vpos = wallargs.texcoords.vpos, vstepX = wallargs.texcoords.vstepX, vstepY = wallargs.texcoords.vstepY;
|
||||
float wpos = wallargs.texcoords.wpos, wstepX = wallargs.texcoords.wstepX, wstepY = wallargs.texcoords.wstepY;
|
||||
float startX = wallargs.texcoords.startX;
|
||||
|
||||
int x1 = wallargs.x1;
|
||||
int x2 = wallargs.x2;
|
||||
|
||||
upos += ustepX * (x1 + 0.5f - startX);
|
||||
vpos += vstepX * (x1 + 0.5f - startX);
|
||||
wpos += wstepX * (x1 + 0.5f - startX);
|
||||
|
||||
float centerY = wallargs.CenterY;
|
||||
centerY -= 0.5f;
|
||||
|
||||
auto uwal = wallargs.uwal;
|
||||
auto dwal = wallargs.dwal;
|
||||
for (int x = x1; x < x2; x++)
|
||||
{
|
||||
int y1 = uwal[x];
|
||||
int y2 = dwal[x];
|
||||
if (y2 > y1)
|
||||
{
|
||||
if (!fixed) drawerargs.SetLight(curlight, shade);
|
||||
if (haslights)
|
||||
SetLights(drawerargs, x, y1);
|
||||
else
|
||||
drawerargs.dc_num_lights = 0;
|
||||
|
||||
float dy = (y1 - centerY);
|
||||
float u = upos + ustepY * dy;
|
||||
float v = vpos + vstepY * dy;
|
||||
float w = wpos + wstepY * dy;
|
||||
float scaleU = ustepX;
|
||||
float scaleV = vstepY;
|
||||
w = 1.0f / w;
|
||||
u *= w;
|
||||
v *= w;
|
||||
scaleU *= w;
|
||||
scaleV *= w;
|
||||
|
||||
uint32_t texelX = (uint32_t)(int64_t)((u - std::floor(u)) * 0x1'0000'0000LL);
|
||||
uint32_t texelY = (uint32_t)(int64_t)((v - std::floor(v)) * 0x1'0000'0000LL);
|
||||
uint32_t texelStepX = (uint32_t)(int64_t)(scaleU * 0x1'0000'0000LL);
|
||||
uint32_t texelStepY = (uint32_t)(int64_t)(scaleV * 0x1'0000'0000LL);
|
||||
|
||||
if (wallargs.fracbits != 32)
|
||||
DrawWallColumn8(thread, drawerargs, x, y1, y2, texelX, texelY, texelStepY);
|
||||
else
|
||||
DrawWallColumn32(thread, drawerargs, x, y1, y2, texelX, texelY, texelStepX, texelStepY);
|
||||
}
|
||||
|
||||
upos += ustepX;
|
||||
vpos += vstepX;
|
||||
wpos += wstepX;
|
||||
curlight += lightstep;
|
||||
}
|
||||
|
||||
if (r_modelscene)
|
||||
{
|
||||
for (int x = x1; x < x2; x++)
|
||||
{
|
||||
int y1 = uwal[x];
|
||||
int y2 = dwal[x];
|
||||
if (y2 > y1)
|
||||
{
|
||||
int count = y2 - y1;
|
||||
|
||||
float w1 = 1.0f / wallargs.WallC.sz1;
|
||||
float w2 = 1.0f / wallargs.WallC.sz2;
|
||||
float t = (x - wallargs.WallC.sx1 + 0.5f) / (wallargs.WallC.sx2 - wallargs.WallC.sx1);
|
||||
float wcol = w1 * (1.0f - t) + w2 * t;
|
||||
float zcol = 1.0f / wcol;
|
||||
float zbufferdepth = 1.0f / (zcol / wallargs.FocalTangent);
|
||||
|
||||
drawerargs.SetDest(x, y1);
|
||||
drawerargs.SetCount(count);
|
||||
DrawDepthColumn(thread, drawerargs, zbufferdepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawWallCommand::DrawWallColumn32(DrawerThread* thread, WallColumnDrawerArgs& drawerargs, int x, int y1, int y2, uint32_t texelX, uint32_t texelY, uint32_t texelStepX, uint32_t texelStepY)
|
||||
{
|
||||
int texwidth = wallargs.texwidth;
|
||||
int texheight = wallargs.texheight;
|
||||
|
||||
double xmagnitude = fabs(static_cast<int32_t>(texelStepX)* (1.0 / 0x1'0000'0000LL));
|
||||
double ymagnitude = fabs(static_cast<int32_t>(texelStepY)* (1.0 / 0x1'0000'0000LL));
|
||||
double magnitude = MAX(ymagnitude, xmagnitude);
|
||||
double min_lod = -1000.0;
|
||||
double lod = MAX(log2(magnitude) + r_lod_bias, min_lod);
|
||||
bool magnifying = lod < 0.0f;
|
||||
|
||||
int mipmap_offset = 0;
|
||||
int mip_width = texwidth;
|
||||
int mip_height = texheight;
|
||||
if (wallargs.mipmapped && mip_width > 1 && mip_height > 1)
|
||||
{
|
||||
int level = (int)lod;
|
||||
while (level > 0 && mip_width > 1 && mip_height > 1)
|
||||
{
|
||||
mipmap_offset += mip_width * mip_height;
|
||||
level--;
|
||||
mip_width = MAX(mip_width >> 1, 1);
|
||||
mip_height = MAX(mip_height >> 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t* pixels = static_cast<const uint32_t*>(wallargs.texpixels) + mipmap_offset;
|
||||
fixed_t xxoffset = (texelX >> 16)* mip_width;
|
||||
|
||||
const uint8_t* source;
|
||||
const uint8_t* source2;
|
||||
uint32_t texturefracx;
|
||||
bool filter_nearest = (magnifying && !r_magfilter) || (!magnifying && !r_minfilter);
|
||||
if (filter_nearest)
|
||||
{
|
||||
int tx = (xxoffset >> FRACBITS) % mip_width;
|
||||
source = (uint8_t*)(pixels + tx * mip_height);
|
||||
source2 = nullptr;
|
||||
texturefracx = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
xxoffset -= FRACUNIT / 2;
|
||||
int tx0 = (xxoffset >> FRACBITS) % mip_width;
|
||||
if (tx0 < 0)
|
||||
tx0 += mip_width;
|
||||
int tx1 = (tx0 + 1) % mip_width;
|
||||
source = (uint8_t*)(pixels + tx0 * mip_height);
|
||||
source2 = (uint8_t*)(pixels + tx1 * mip_height);
|
||||
texturefracx = (xxoffset >> (FRACBITS - 4)) & 15;
|
||||
}
|
||||
|
||||
int count = y2 - y1;
|
||||
drawerargs.SetDest(x, y1);
|
||||
drawerargs.SetCount(count);
|
||||
drawerargs.SetTexture(source, source2, mip_height);
|
||||
drawerargs.SetTextureUPos(texturefracx);
|
||||
drawerargs.SetTextureVPos(texelY);
|
||||
drawerargs.SetTextureVStep(texelStepY);
|
||||
DrawColumn(thread, drawerargs);
|
||||
}
|
||||
|
||||
void DrawWallCommand::DrawWallColumn8(DrawerThread* thread, WallColumnDrawerArgs& drawerargs, int x, int y1, int y2, uint32_t texelX, uint32_t texelY, uint32_t texelStepY)
|
||||
{
|
||||
int texwidth = wallargs.texwidth;
|
||||
int texheight = wallargs.texheight;
|
||||
int fracbits = wallargs.fracbits;
|
||||
uint32_t uv_max = texheight << fracbits;
|
||||
|
||||
const uint8_t* pixels = static_cast<const uint8_t*>(wallargs.texpixels) + (((texelX >> 16)* texwidth) >> 16)* texheight;
|
||||
|
||||
texelY = (static_cast<uint64_t>(texelY)* texheight) >> (32 - fracbits);
|
||||
texelStepY = (static_cast<uint64_t>(texelStepY)* texheight) >> (32 - fracbits);
|
||||
|
||||
drawerargs.SetTexture(pixels, nullptr, texheight);
|
||||
drawerargs.SetTextureVStep(texelStepY);
|
||||
|
||||
if (uv_max == 0 || texelStepY == 0) // power of two
|
||||
{
|
||||
int count = y2 - y1;
|
||||
|
||||
drawerargs.SetDest(x, y1);
|
||||
drawerargs.SetCount(count);
|
||||
drawerargs.SetTextureVPos(texelY);
|
||||
DrawColumn(thread, drawerargs);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t left = y2 - y1;
|
||||
int y = y1;
|
||||
while (left > 0)
|
||||
{
|
||||
uint32_t available = uv_max - texelY;
|
||||
uint32_t next_uv_wrap = available / texelStepY;
|
||||
if (available % texelStepY != 0)
|
||||
next_uv_wrap++;
|
||||
uint32_t count = MIN(left, next_uv_wrap);
|
||||
|
||||
drawerargs.SetDest(x, y);
|
||||
drawerargs.SetCount(count);
|
||||
drawerargs.SetTextureVPos(texelY);
|
||||
DrawColumn(thread, drawerargs);
|
||||
|
||||
y += count;
|
||||
left -= count;
|
||||
texelY += texelStepY * count;
|
||||
if (texelY >= uv_max)
|
||||
texelY -= uv_max;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawWallCommand::DrawDepthColumn(DrawerThread* thread, const WallColumnDrawerArgs& args, float idepth)
|
||||
{
|
||||
int x, y, count;
|
||||
|
||||
auto rendertarget = args.Viewport()->RenderTarget;
|
||||
if (rendertarget->IsBgra())
|
||||
{
|
||||
uint32_t* destorg = (uint32_t*)rendertarget->GetPixels();
|
||||
destorg += viewwindowx + viewwindowy * rendertarget->GetPitch();
|
||||
uint32_t* dest = (uint32_t*)args.Dest();
|
||||
int offset = (int)(ptrdiff_t)(dest - destorg);
|
||||
x = offset % rendertarget->GetPitch();
|
||||
y = offset / rendertarget->GetPitch();
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t* destorg = rendertarget->GetPixels();
|
||||
destorg += viewwindowx + viewwindowy * rendertarget->GetPitch();
|
||||
uint8_t* dest = (uint8_t*)args.Dest();
|
||||
int offset = (int)(ptrdiff_t)(dest - destorg);
|
||||
x = offset % rendertarget->GetPitch();
|
||||
y = offset / rendertarget->GetPitch();
|
||||
}
|
||||
count = args.Count();
|
||||
|
||||
auto zbuffer = PolyZBuffer::Instance();
|
||||
int pitch = PolyStencilBuffer::Instance()->Width();
|
||||
float* values = zbuffer->Values() + y * pitch + x;
|
||||
int cnt = count;
|
||||
|
||||
values = thread->dest_for_thread(y, pitch, values);
|
||||
cnt = thread->count_for_thread(y, cnt);
|
||||
pitch *= thread->num_cores;
|
||||
|
||||
float depth = idepth;
|
||||
for (int i = 0; i < cnt; i++)
|
||||
{
|
||||
*values = depth;
|
||||
values += pitch;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawWallCommand::SetLights(WallColumnDrawerArgs& drawerargs, int x, int y1)
|
||||
{
|
||||
bool mirror = !!(wallargs.PortalMirrorFlags & RF_XFLIP);
|
||||
int tx = x;
|
||||
if (mirror)
|
||||
tx = viewwidth - tx - 1;
|
||||
|
||||
// Find column position in view space
|
||||
float w1 = 1.0f / wallargs.WallC.sz1;
|
||||
float w2 = 1.0f / wallargs.WallC.sz2;
|
||||
float t = (x - wallargs.WallC.sx1 + 0.5f) / (wallargs.WallC.sx2 - wallargs.WallC.sx1);
|
||||
float wcol = w1 * (1.0f - t) + w2 * t;
|
||||
float zcol = 1.0f / wcol;
|
||||
|
||||
drawerargs.dc_viewpos.X = (float)((tx + 0.5 - wallargs.CenterX) / wallargs.CenterX * zcol);
|
||||
drawerargs.dc_viewpos.Y = zcol;
|
||||
drawerargs.dc_viewpos.Z = (float)((wallargs.CenterY - y1 - 0.5) / wallargs.InvZtoScale * zcol);
|
||||
drawerargs.dc_viewpos_step.Z = (float)(-zcol / wallargs.InvZtoScale);
|
||||
|
||||
drawerargs.dc_num_lights = 0;
|
||||
|
||||
// Setup lights for column
|
||||
FLightNode* cur_node = drawerargs.LightList();
|
||||
while (cur_node)
|
||||
{
|
||||
if (cur_node->lightsource->IsActive())
|
||||
{
|
||||
double lightX = cur_node->lightsource->X() - wallargs.ViewpointPos.X;
|
||||
double lightY = cur_node->lightsource->Y() - wallargs.ViewpointPos.Y;
|
||||
double lightZ = cur_node->lightsource->Z() - wallargs.ViewpointPos.Z;
|
||||
|
||||
float lx = (float)(lightX * wallargs.Sin - lightY * wallargs.Cos) - drawerargs.dc_viewpos.X;
|
||||
float ly = (float)(lightX * wallargs.TanCos + lightY * wallargs.TanSin) - drawerargs.dc_viewpos.Y;
|
||||
float lz = (float)lightZ;
|
||||
|
||||
// Precalculate the constant part of the dot here so the drawer doesn't have to.
|
||||
bool is_point_light = cur_node->lightsource->IsAttenuated();
|
||||
float lconstant = lx * lx + ly * ly;
|
||||
float nlconstant = is_point_light ? lx * drawerargs.dc_normal.X + ly * drawerargs.dc_normal.Y : 0.0f;
|
||||
|
||||
// Include light only if it touches this column
|
||||
float radius = cur_node->lightsource->GetRadius();
|
||||
if (radius * radius >= lconstant && nlconstant >= 0.0f)
|
||||
{
|
||||
uint32_t red = cur_node->lightsource->GetRed();
|
||||
uint32_t green = cur_node->lightsource->GetGreen();
|
||||
uint32_t blue = cur_node->lightsource->GetBlue();
|
||||
|
||||
auto& light = drawerargs.dc_lights[drawerargs.dc_num_lights++];
|
||||
light.x = lconstant;
|
||||
light.y = nlconstant;
|
||||
light.z = lz;
|
||||
light.radius = 256.0f / cur_node->lightsource->GetRadius();
|
||||
light.color = (red << 16) | (green << 8) | blue;
|
||||
|
||||
if (drawerargs.dc_num_lights == WallColumnDrawerArgs::MAX_DRAWER_LIGHTS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cur_node = cur_node->nextLight;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class DepthSkyColumnCommand : public DrawerCommand
|
||||
{
|
||||
public:
|
||||
DepthSkyColumnCommand(const SkyDrawerArgs &args, float idepth) : idepth(idepth)
|
||||
{
|
||||
auto rendertarget = args.Viewport()->RenderTarget;
|
||||
if (rendertarget->IsBgra())
|
||||
|
@ -359,12 +669,7 @@ namespace swrenderer
|
|||
|
||||
void SWPixelFormatDrawers::DrawDepthSkyColumn(const SkyDrawerArgs &args, float idepth)
|
||||
{
|
||||
Queue->Push<DepthColumnCommand>(args, idepth);
|
||||
}
|
||||
|
||||
void SWPixelFormatDrawers::DrawDepthWallColumn(const WallDrawerArgs &args, float idepth)
|
||||
{
|
||||
Queue->Push<DepthColumnCommand>(args, idepth);
|
||||
Queue->Push<DepthSkyColumnCommand>(args, idepth);
|
||||
}
|
||||
|
||||
void SWPixelFormatDrawers::DrawDepthSpan(const SpanDrawerArgs &args, float idepth1, float idepth2)
|
||||
|
|
|
@ -57,12 +57,12 @@ namespace swrenderer
|
|||
public:
|
||||
SWPixelFormatDrawers(DrawerCommandQueuePtr queue) : Queue(queue) { }
|
||||
virtual ~SWPixelFormatDrawers() { }
|
||||
virtual void DrawWallColumn(const WallDrawerArgs &args) = 0;
|
||||
virtual void DrawWallMaskedColumn(const WallDrawerArgs &args) = 0;
|
||||
virtual void DrawWallAddColumn(const WallDrawerArgs &args) = 0;
|
||||
virtual void DrawWallAddClampColumn(const WallDrawerArgs &args) = 0;
|
||||
virtual void DrawWallSubClampColumn(const WallDrawerArgs &args) = 0;
|
||||
virtual void DrawWallRevSubClampColumn(const WallDrawerArgs &args) = 0;
|
||||
virtual void DrawWall(const WallDrawerArgs &args) = 0;
|
||||
virtual void DrawWallMasked(const WallDrawerArgs &args) = 0;
|
||||
virtual void DrawWallAdd(const WallDrawerArgs &args) = 0;
|
||||
virtual void DrawWallAddClamp(const WallDrawerArgs &args) = 0;
|
||||
virtual void DrawWallSubClamp(const WallDrawerArgs &args) = 0;
|
||||
virtual void DrawWallRevSubClamp(const WallDrawerArgs &args) = 0;
|
||||
virtual void DrawSingleSkyColumn(const SkyDrawerArgs &args) = 0;
|
||||
virtual void DrawDoubleSkyColumn(const SkyDrawerArgs &args) = 0;
|
||||
virtual void DrawColumn(const SpriteDrawerArgs &args) = 0;
|
||||
|
@ -96,7 +96,6 @@ namespace swrenderer
|
|||
virtual void DrawFogBoundaryLine(const SpanDrawerArgs &args) = 0;
|
||||
|
||||
void DrawDepthSkyColumn(const SkyDrawerArgs &args, float idepth);
|
||||
void DrawDepthWallColumn(const WallDrawerArgs &args, float idepth);
|
||||
void DrawDepthSpan(const SpanDrawerArgs &args, float idepth1, float idepth2);
|
||||
|
||||
DrawerCommandQueuePtr Queue;
|
||||
|
|
|
@ -93,10 +93,6 @@ EXTERN_CVAR(Int, gl_particles_style)
|
|||
|
||||
namespace swrenderer
|
||||
{
|
||||
PalWall1Command::PalWall1Command(const WallDrawerArgs &args) : args(args)
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t PalWall1Command::AddLights(const DrawerLight *lights, int num_lights, float viewpos_z, uint8_t fg, uint8_t material)
|
||||
{
|
||||
uint32_t lit_r = 0;
|
||||
|
@ -150,7 +146,7 @@ namespace swrenderer
|
|||
return RGB256k.All[((lit_r >> 2) << 12) | ((lit_g >> 2) << 6) | (lit_b >> 2)];
|
||||
}
|
||||
|
||||
void DrawWall1PalCommand::Execute(DrawerThread *thread)
|
||||
void DrawWall1PalCommand::DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args)
|
||||
{
|
||||
uint32_t fracstep = args.TextureVStep();
|
||||
uint32_t frac = args.TextureVPos();
|
||||
|
@ -160,7 +156,7 @@ namespace swrenderer
|
|||
uint8_t *dest = args.Dest();
|
||||
int bits = args.TextureFracBits();
|
||||
int pitch = args.Viewport()->RenderTarget->GetPitch();
|
||||
DrawerLight *dynlights = args.dc_lights;
|
||||
const DrawerLight *dynlights = args.dc_lights;
|
||||
int num_dynlights = args.dc_num_lights;
|
||||
float viewpos_z = args.dc_viewpos.Z;
|
||||
float step_viewpos_z = args.dc_viewpos_step.Z;
|
||||
|
@ -201,7 +197,7 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
|
||||
void DrawWallMasked1PalCommand::Execute(DrawerThread *thread)
|
||||
void DrawWallMasked1PalCommand::DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args)
|
||||
{
|
||||
uint32_t fracstep = args.TextureVStep();
|
||||
uint32_t frac = args.TextureVPos();
|
||||
|
@ -211,7 +207,7 @@ namespace swrenderer
|
|||
uint8_t *dest = args.Dest();
|
||||
int bits = args.TextureFracBits();
|
||||
int pitch = args.Viewport()->RenderTarget->GetPitch();
|
||||
DrawerLight *dynlights = args.dc_lights;
|
||||
const DrawerLight *dynlights = args.dc_lights;
|
||||
int num_dynlights = args.dc_num_lights;
|
||||
float viewpos_z = args.dc_viewpos.Z;
|
||||
float step_viewpos_z = args.dc_viewpos_step.Z;
|
||||
|
@ -260,7 +256,7 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
|
||||
void DrawWallAdd1PalCommand::Execute(DrawerThread *thread)
|
||||
void DrawWallAdd1PalCommand::DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args)
|
||||
{
|
||||
uint32_t fracstep = args.TextureVStep();
|
||||
uint32_t frac = args.TextureVPos();
|
||||
|
@ -322,7 +318,7 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
|
||||
void DrawWallAddClamp1PalCommand::Execute(DrawerThread *thread)
|
||||
void DrawWallAddClamp1PalCommand::DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args)
|
||||
{
|
||||
uint32_t fracstep = args.TextureVStep();
|
||||
uint32_t frac = args.TextureVPos();
|
||||
|
@ -332,7 +328,7 @@ namespace swrenderer
|
|||
uint8_t *dest = args.Dest();
|
||||
int bits = args.TextureFracBits();
|
||||
int pitch = args.Viewport()->RenderTarget->GetPitch();
|
||||
DrawerLight *dynlights = args.dc_lights;
|
||||
const DrawerLight *dynlights = args.dc_lights;
|
||||
int num_dynlights = args.dc_num_lights;
|
||||
float viewpos_z = args.dc_viewpos.Z;
|
||||
float step_viewpos_z = args.dc_viewpos_step.Z;
|
||||
|
@ -396,7 +392,7 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
|
||||
void DrawWallSubClamp1PalCommand::Execute(DrawerThread *thread)
|
||||
void DrawWallSubClamp1PalCommand::DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args)
|
||||
{
|
||||
uint32_t fracstep = args.TextureVStep();
|
||||
uint32_t frac = args.TextureVPos();
|
||||
|
@ -406,7 +402,7 @@ namespace swrenderer
|
|||
uint8_t *dest = args.Dest();
|
||||
int bits = args.TextureFracBits();
|
||||
int pitch = args.Viewport()->RenderTarget->GetPitch();
|
||||
DrawerLight *dynlights = args.dc_lights;
|
||||
const DrawerLight *dynlights = args.dc_lights;
|
||||
int num_dynlights = args.dc_num_lights;
|
||||
float viewpos_z = args.dc_viewpos.Z;
|
||||
float step_viewpos_z = args.dc_viewpos_step.Z;
|
||||
|
@ -469,7 +465,7 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
|
||||
void DrawWallRevSubClamp1PalCommand::Execute(DrawerThread *thread)
|
||||
void DrawWallRevSubClamp1PalCommand::DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args)
|
||||
{
|
||||
uint32_t fracstep = args.TextureVStep();
|
||||
uint32_t frac = args.TextureVPos();
|
||||
|
@ -479,7 +475,7 @@ namespace swrenderer
|
|||
uint8_t *dest = args.Dest();
|
||||
int bits = args.TextureFracBits();
|
||||
int pitch = args.Viewport()->RenderTarget->GetPitch();
|
||||
DrawerLight *dynlights = args.dc_lights;
|
||||
const DrawerLight *dynlights = args.dc_lights;
|
||||
int num_dynlights = args.dc_num_lights;
|
||||
float viewpos_z = args.dc_viewpos.Z;
|
||||
float step_viewpos_z = args.dc_viewpos_step.Z;
|
||||
|
|
|
@ -8,26 +8,140 @@
|
|||
#include "swrenderer/viewport/r_spandrawer.h"
|
||||
#include "swrenderer/viewport/r_walldrawer.h"
|
||||
#include "swrenderer/viewport/r_spritedrawer.h"
|
||||
#include "swrenderer/r_swcolormaps.h"
|
||||
|
||||
struct FSWColormap;
|
||||
|
||||
namespace swrenderer
|
||||
{
|
||||
class PalWall1Command : public DrawerCommand
|
||||
class WallColumnDrawerArgs
|
||||
{
|
||||
public:
|
||||
PalWall1Command(const WallDrawerArgs &args);
|
||||
WallColumnDrawerArgs(const WallDrawerArgs& wallargs) : wallargs(wallargs) { }
|
||||
|
||||
void SetDest(int x, int y)
|
||||
{
|
||||
dc_dest = Viewport()->GetDest(x, y);
|
||||
dc_dest_y = y;
|
||||
}
|
||||
|
||||
void SetCount(int count) { dc_count = count; }
|
||||
void SetTexture(const uint8_t* pixels, const uint8_t* pixels2, int height)
|
||||
{
|
||||
dc_source = pixels;
|
||||
dc_source2 = pixels2;
|
||||
dc_textureheight = height;
|
||||
}
|
||||
void SetTextureFracBits(int bits) { dc_wall_fracbits = bits; }
|
||||
void SetTextureUPos(uint32_t pos) { dc_texturefracx = pos; }
|
||||
void SetTextureVPos(fixed_t pos) { dc_texturefrac = pos; }
|
||||
void SetTextureVStep(fixed_t step) { dc_iscale = step; }
|
||||
|
||||
void SetLight(float light, int shade) { mLight = light; mShade = shade; }
|
||||
|
||||
uint8_t* Dest() const { return dc_dest; }
|
||||
int DestY() const { return dc_dest_y; }
|
||||
int Count() const { return dc_count; }
|
||||
|
||||
uint32_t* SrcBlend() const { return wallargs.SrcBlend(); }
|
||||
uint32_t* DestBlend() const { return wallargs.DestBlend(); }
|
||||
fixed_t SrcAlpha() const { return wallargs.SrcAlpha(); }
|
||||
fixed_t DestAlpha() const { return wallargs.DestAlpha(); }
|
||||
|
||||
uint32_t TextureUPos() const { return dc_texturefracx; }
|
||||
fixed_t TextureVPos() const { return dc_texturefrac; }
|
||||
fixed_t TextureVStep() const { return dc_iscale; }
|
||||
|
||||
const uint8_t* TexturePixels() const { return dc_source; }
|
||||
const uint8_t* TexturePixels2() const { return dc_source2; }
|
||||
uint32_t TextureHeight() const { return dc_textureheight; }
|
||||
|
||||
int TextureFracBits() const { return dc_wall_fracbits; }
|
||||
|
||||
FVector3 dc_normal = { 0,0,0 };
|
||||
FVector3 dc_viewpos = { 0,0,0 };
|
||||
FVector3 dc_viewpos_step = { 0,0,0 };
|
||||
enum { MAX_DRAWER_LIGHTS = 16 };
|
||||
DrawerLight dc_lights[MAX_DRAWER_LIGHTS];
|
||||
int dc_num_lights = 0;
|
||||
|
||||
RenderViewport* Viewport() const { return wallargs.Viewport(); }
|
||||
|
||||
uint8_t* Colormap(RenderViewport* viewport) const
|
||||
{
|
||||
auto basecolormap = wallargs.BaseColormap();
|
||||
if (basecolormap)
|
||||
{
|
||||
if (viewport->RenderTarget->IsBgra())
|
||||
return basecolormap->Maps;
|
||||
else
|
||||
return basecolormap->Maps + (GETPALOOKUP(mLight, mShade) << COLORMAPSHIFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
return wallargs.TranslationMap();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* TranslationMap() const { return wallargs.TranslationMap(); }
|
||||
|
||||
ShadeConstants ColormapConstants() const { return wallargs.ColormapConstants(); }
|
||||
fixed_t Light() const { return LIGHTSCALE(mLight, mShade); }
|
||||
|
||||
FLightNode* LightList() const { return wallargs.lightlist; }
|
||||
|
||||
private:
|
||||
const WallDrawerArgs& wallargs;
|
||||
|
||||
uint8_t* dc_dest = nullptr;
|
||||
int dc_dest_y = 0;
|
||||
int dc_count = 0;
|
||||
|
||||
fixed_t dc_iscale = 0;
|
||||
fixed_t dc_texturefrac = 0;
|
||||
uint32_t dc_texturefracx = 0;
|
||||
uint32_t dc_textureheight = 0;
|
||||
const uint8_t* dc_source = nullptr;
|
||||
const uint8_t* dc_source2 = nullptr;
|
||||
int dc_wall_fracbits = 0;
|
||||
|
||||
float mLight = 0.0f;
|
||||
int mShade = 0;
|
||||
};
|
||||
|
||||
class DrawWallCommand : public DrawerCommand
|
||||
{
|
||||
public:
|
||||
DrawWallCommand(const WallDrawerArgs& args);
|
||||
void Execute(DrawerThread* thread) override;
|
||||
|
||||
protected:
|
||||
virtual void DrawColumn(DrawerThread* thread, const WallColumnDrawerArgs& args) = 0;
|
||||
|
||||
private:
|
||||
void DrawWallColumn32(DrawerThread* thread, WallColumnDrawerArgs& drawerargs, int x, int y1, int y2, uint32_t texelX, uint32_t texelY, uint32_t texelStepX, uint32_t texelStepY);
|
||||
void DrawWallColumn8(DrawerThread* thread, WallColumnDrawerArgs& drawerargs, int x, int y1, int y2, uint32_t texelX, uint32_t texelY, uint32_t texelStepY);
|
||||
void DrawDepthColumn(DrawerThread* thread, const WallColumnDrawerArgs& args, float idepth);
|
||||
void SetLights(WallColumnDrawerArgs& drawerargs, int x, int y1);
|
||||
|
||||
WallDrawerArgs wallargs;
|
||||
};
|
||||
|
||||
class PalWall1Command : public DrawWallCommand
|
||||
{
|
||||
public:
|
||||
PalWall1Command(const WallDrawerArgs &args) : DrawWallCommand(args) { }
|
||||
|
||||
protected:
|
||||
inline static uint8_t AddLights(const DrawerLight *lights, int num_lights, float viewpos_z, uint8_t fg, uint8_t material);
|
||||
|
||||
WallDrawerArgs args;
|
||||
};
|
||||
|
||||
class DrawWall1PalCommand : public PalWall1Command { public: using PalWall1Command::PalWall1Command; void Execute(DrawerThread *thread) override; };
|
||||
class DrawWallMasked1PalCommand : public PalWall1Command { public: using PalWall1Command::PalWall1Command; void Execute(DrawerThread *thread) override; };
|
||||
class DrawWallAdd1PalCommand : public PalWall1Command { public: using PalWall1Command::PalWall1Command; void Execute(DrawerThread *thread) override; };
|
||||
class DrawWallAddClamp1PalCommand : public PalWall1Command { public: using PalWall1Command::PalWall1Command; void Execute(DrawerThread *thread) override; };
|
||||
class DrawWallSubClamp1PalCommand : public PalWall1Command { public: using PalWall1Command::PalWall1Command; void Execute(DrawerThread *thread) override; };
|
||||
class DrawWallRevSubClamp1PalCommand : public PalWall1Command { public: using PalWall1Command::PalWall1Command; void Execute(DrawerThread *thread) override; };
|
||||
class DrawWall1PalCommand : public PalWall1Command { public: using PalWall1Command::PalWall1Command; void DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) override; };
|
||||
class DrawWallMasked1PalCommand : public PalWall1Command { public: using PalWall1Command::PalWall1Command; void DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) override; };
|
||||
class DrawWallAdd1PalCommand : public PalWall1Command { public: using PalWall1Command::PalWall1Command; void DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) override; };
|
||||
class DrawWallAddClamp1PalCommand : public PalWall1Command { public: using PalWall1Command::PalWall1Command; void DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) override; };
|
||||
class DrawWallSubClamp1PalCommand : public PalWall1Command { public: using PalWall1Command::PalWall1Command; void DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) override; };
|
||||
class DrawWallRevSubClamp1PalCommand : public PalWall1Command { public: using PalWall1Command::PalWall1Command; void DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) override; };
|
||||
|
||||
class PalSkyCommand : public DrawerCommand
|
||||
{
|
||||
|
@ -230,20 +344,20 @@ namespace swrenderer
|
|||
public:
|
||||
using SWPixelFormatDrawers::SWPixelFormatDrawers;
|
||||
|
||||
void DrawWallColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWall1PalCommand>(args); }
|
||||
void DrawWallMaskedColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallMasked1PalCommand>(args); }
|
||||
void DrawWall(const WallDrawerArgs &args) override { Queue->Push<DrawWall1PalCommand>(args); }
|
||||
void DrawWallMasked(const WallDrawerArgs &args) override { Queue->Push<DrawWallMasked1PalCommand>(args); }
|
||||
|
||||
void DrawWallAddColumn(const WallDrawerArgs &args) override
|
||||
void DrawWallAdd(const WallDrawerArgs &args) override
|
||||
{
|
||||
if (args.dc_num_lights == 0)
|
||||
if (!args.lightlist)
|
||||
Queue->Push<DrawWallAdd1PalCommand>(args);
|
||||
else
|
||||
Queue->Push<DrawWallAddClamp1PalCommand>(args);
|
||||
}
|
||||
|
||||
void DrawWallAddClampColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallAddClamp1PalCommand>(args); }
|
||||
void DrawWallSubClampColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallSubClamp1PalCommand>(args); }
|
||||
void DrawWallRevSubClampColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallRevSubClamp1PalCommand>(args); }
|
||||
void DrawWallAddClamp(const WallDrawerArgs &args) override { Queue->Push<DrawWallAddClamp1PalCommand>(args); }
|
||||
void DrawWallSubClamp(const WallDrawerArgs &args) override { Queue->Push<DrawWallSubClamp1PalCommand>(args); }
|
||||
void DrawWallRevSubClamp(const WallDrawerArgs &args) override { Queue->Push<DrawWallRevSubClamp1PalCommand>(args); }
|
||||
void DrawSingleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push<DrawSingleSky1PalCommand>(args); }
|
||||
void DrawDoubleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push<DrawDoubleSky1PalCommand>(args); }
|
||||
void DrawColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnPalCommand>(args); }
|
||||
|
|
|
@ -80,32 +80,32 @@ CVAR(Float, r_lod_bias, -1.5, 0); // To do: add CVAR_ARCHIVE | CVAR_GLOBALCONFIG
|
|||
|
||||
namespace swrenderer
|
||||
{
|
||||
void SWTruecolorDrawers::DrawWallColumn(const WallDrawerArgs &args)
|
||||
void SWTruecolorDrawers::DrawWall(const WallDrawerArgs &args)
|
||||
{
|
||||
Queue->Push<DrawWall32Command>(args);
|
||||
}
|
||||
|
||||
void SWTruecolorDrawers::DrawWallMaskedColumn(const WallDrawerArgs &args)
|
||||
void SWTruecolorDrawers::DrawWallMasked(const WallDrawerArgs &args)
|
||||
{
|
||||
Queue->Push<DrawWallMasked32Command>(args);
|
||||
}
|
||||
|
||||
void SWTruecolorDrawers::DrawWallAddColumn(const WallDrawerArgs &args)
|
||||
void SWTruecolorDrawers::DrawWallAdd(const WallDrawerArgs &args)
|
||||
{
|
||||
Queue->Push<DrawWallAddClamp32Command>(args);
|
||||
}
|
||||
|
||||
void SWTruecolorDrawers::DrawWallAddClampColumn(const WallDrawerArgs &args)
|
||||
void SWTruecolorDrawers::DrawWallAddClamp(const WallDrawerArgs &args)
|
||||
{
|
||||
Queue->Push<DrawWallAddClamp32Command>(args);
|
||||
}
|
||||
|
||||
void SWTruecolorDrawers::DrawWallSubClampColumn(const WallDrawerArgs &args)
|
||||
void SWTruecolorDrawers::DrawWallSubClamp(const WallDrawerArgs &args)
|
||||
{
|
||||
Queue->Push<DrawWallSubClamp32Command>(args);
|
||||
}
|
||||
|
||||
void SWTruecolorDrawers::DrawWallRevSubClampColumn(const WallDrawerArgs &args)
|
||||
void SWTruecolorDrawers::DrawWallRevSubClamp(const WallDrawerArgs &args)
|
||||
{
|
||||
Queue->Push<DrawWallRevSubClamp32Command>(args);
|
||||
}
|
||||
|
|
|
@ -244,12 +244,12 @@ namespace swrenderer
|
|||
public:
|
||||
using SWPixelFormatDrawers::SWPixelFormatDrawers;
|
||||
|
||||
void DrawWallColumn(const WallDrawerArgs &args) override;
|
||||
void DrawWallMaskedColumn(const WallDrawerArgs &args) override;
|
||||
void DrawWallAddColumn(const WallDrawerArgs &args) override;
|
||||
void DrawWallAddClampColumn(const WallDrawerArgs &args) override;
|
||||
void DrawWallSubClampColumn(const WallDrawerArgs &args) override;
|
||||
void DrawWallRevSubClampColumn(const WallDrawerArgs &args) override;
|
||||
void DrawWall(const WallDrawerArgs &args) override;
|
||||
void DrawWallMasked(const WallDrawerArgs &args) override;
|
||||
void DrawWallAdd(const WallDrawerArgs &args) override;
|
||||
void DrawWallAddClamp(const WallDrawerArgs &args) override;
|
||||
void DrawWallSubClamp(const WallDrawerArgs &args) override;
|
||||
void DrawWallRevSubClamp(const WallDrawerArgs &args) override;
|
||||
void DrawSingleSkyColumn(const SkyDrawerArgs &args) override;
|
||||
void DrawDoubleSkyColumn(const SkyDrawerArgs &args) override;
|
||||
void DrawColumn(const SpriteDrawerArgs &args) override;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "swrenderer/drawers/r_draw_pal.h"
|
||||
#include "swrenderer/drawers/r_draw_rgba.h"
|
||||
#include "swrenderer/viewport/r_walldrawer.h"
|
||||
|
||||
|
@ -46,15 +47,12 @@ namespace swrenderer
|
|||
}
|
||||
|
||||
template<typename BlendT>
|
||||
class DrawWall32T : public DrawerCommand
|
||||
class DrawWall32T : public DrawWallCommand
|
||||
{
|
||||
protected:
|
||||
WallDrawerArgs args;
|
||||
|
||||
public:
|
||||
DrawWall32T(const WallDrawerArgs &drawerargs) : args(drawerargs) { }
|
||||
DrawWall32T(const WallDrawerArgs &drawerargs) : DrawWallCommand(drawerargs) { }
|
||||
|
||||
void Execute(DrawerThread *thread) override
|
||||
void DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) override
|
||||
{
|
||||
using namespace DrawWall32TModes;
|
||||
|
||||
|
@ -64,21 +62,21 @@ namespace swrenderer
|
|||
if (shade_constants.simple_shade)
|
||||
{
|
||||
if (is_nearest_filter)
|
||||
Loop<SimpleShade, NearestFilter>(thread, shade_constants);
|
||||
Loop<SimpleShade, NearestFilter>(thread, args, shade_constants);
|
||||
else
|
||||
Loop<SimpleShade, LinearFilter>(thread, shade_constants);
|
||||
Loop<SimpleShade, LinearFilter>(thread, args, shade_constants);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_nearest_filter)
|
||||
Loop<AdvancedShade, NearestFilter>(thread, shade_constants);
|
||||
Loop<AdvancedShade, NearestFilter>(thread, args, shade_constants);
|
||||
else
|
||||
Loop<AdvancedShade, LinearFilter>(thread, shade_constants);
|
||||
Loop<AdvancedShade, LinearFilter>(thread, args, shade_constants);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ShadeModeT, typename FilterModeT>
|
||||
FORCEINLINE void Loop(DrawerThread *thread, ShadeConstants shade_constants)
|
||||
FORCEINLINE void Loop(DrawerThread *thread, const WallColumnDrawerArgs& args, ShadeConstants shade_constants)
|
||||
{
|
||||
using namespace DrawWall32TModes;
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "swrenderer/drawers/r_draw_pal.h"
|
||||
#include "swrenderer/drawers/r_draw_rgba.h"
|
||||
#include "swrenderer/viewport/r_walldrawer.h"
|
||||
|
||||
|
@ -46,15 +47,12 @@ namespace swrenderer
|
|||
}
|
||||
|
||||
template<typename BlendT>
|
||||
class DrawWall32T : public DrawerCommand
|
||||
class DrawWall32T : public DrawWallCommand
|
||||
{
|
||||
protected:
|
||||
WallDrawerArgs args;
|
||||
|
||||
public:
|
||||
DrawWall32T(const WallDrawerArgs &drawerargs) : args(drawerargs) { }
|
||||
DrawWall32T(const WallDrawerArgs &drawerargs) : DrawWallCommand(drawerargs) { }
|
||||
|
||||
void Execute(DrawerThread *thread) override
|
||||
void DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) override
|
||||
{
|
||||
using namespace DrawWall32TModes;
|
||||
|
||||
|
@ -64,21 +62,21 @@ namespace swrenderer
|
|||
if (shade_constants.simple_shade)
|
||||
{
|
||||
if (is_nearest_filter)
|
||||
Loop<SimpleShade, NearestFilter>(thread, shade_constants);
|
||||
Loop<SimpleShade, NearestFilter>(thread, args, shade_constants);
|
||||
else
|
||||
Loop<SimpleShade, LinearFilter>(thread, shade_constants);
|
||||
Loop<SimpleShade, LinearFilter>(thread, args, shade_constants);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_nearest_filter)
|
||||
Loop<AdvancedShade, NearestFilter>(thread, shade_constants);
|
||||
Loop<AdvancedShade, NearestFilter>(thread, args, shade_constants);
|
||||
else
|
||||
Loop<AdvancedShade, LinearFilter>(thread, shade_constants);
|
||||
Loop<AdvancedShade, LinearFilter>(thread, args, shade_constants);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ShadeModeT, typename FilterModeT>
|
||||
FORCEINLINE void VECTORCALL Loop(DrawerThread *thread, ShadeConstants shade_constants)
|
||||
FORCEINLINE void VECTORCALL Loop(DrawerThread *thread, const WallColumnDrawerArgs& args, ShadeConstants shade_constants)
|
||||
{
|
||||
using namespace DrawWall32TModes;
|
||||
|
||||
|
|
|
@ -120,111 +120,6 @@ namespace swrenderer
|
|||
ProcessNormalWall(up, dwal, texcoords);
|
||||
}
|
||||
|
||||
static void DrawWallColumn32(RenderThread* thread, WallDrawerArgs& drawerargs, int x, int y1, int y2, uint32_t texelX, uint32_t texelY, uint32_t texelStepX, uint32_t texelStepY, FSoftwareTexture* pic, int texwidth, int texheight)
|
||||
{
|
||||
double xmagnitude = fabs(static_cast<int32_t>(texelStepX) * (1.0 / 0x1'0000'0000LL));
|
||||
double ymagnitude = fabs(static_cast<int32_t>(texelStepY) * (1.0 / 0x1'0000'0000LL));
|
||||
double magnitude = MAX(ymagnitude, xmagnitude);
|
||||
double min_lod = -1000.0;
|
||||
double lod = MAX(log2(magnitude) + r_lod_bias, min_lod);
|
||||
bool magnifying = lod < 0.0f;
|
||||
|
||||
int mipmap_offset = 0;
|
||||
int mip_width = texwidth;
|
||||
int mip_height = texheight;
|
||||
if (r_mipmap && pic->Mipmapped() && mip_width > 1 && mip_height > 1)
|
||||
{
|
||||
int level = (int)lod;
|
||||
while (level > 0 && mip_width > 1 && mip_height > 1)
|
||||
{
|
||||
mipmap_offset += mip_width * mip_height;
|
||||
level--;
|
||||
mip_width = MAX(mip_width >> 1, 1);
|
||||
mip_height = MAX(mip_height >> 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t* pixels = pic->GetPixelsBgra() + mipmap_offset;
|
||||
fixed_t xxoffset = (texelX >> 16) * mip_width;
|
||||
|
||||
const uint8_t* source;
|
||||
const uint8_t* source2;
|
||||
uint32_t texturefracx;
|
||||
bool filter_nearest = (magnifying && !r_magfilter) || (!magnifying && !r_minfilter);
|
||||
if (filter_nearest)
|
||||
{
|
||||
int tx = (xxoffset >> FRACBITS) % mip_width;
|
||||
source = (uint8_t*)(pixels + tx * mip_height);
|
||||
source2 = nullptr;
|
||||
texturefracx = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
xxoffset -= FRACUNIT / 2;
|
||||
int tx0 = (xxoffset >> FRACBITS) % mip_width;
|
||||
if (tx0 < 0)
|
||||
tx0 += mip_width;
|
||||
int tx1 = (tx0 + 1) % mip_width;
|
||||
source = (uint8_t*)(pixels + tx0 * mip_height);
|
||||
source2 = (uint8_t*)(pixels + tx1 * mip_height);
|
||||
texturefracx = (xxoffset >> (FRACBITS - 4)) & 15;
|
||||
}
|
||||
|
||||
int count = y2 - y1;
|
||||
drawerargs.SetDest(thread->Viewport.get(), x, y1);
|
||||
drawerargs.SetCount(count);
|
||||
drawerargs.SetTexture(source, source2, mip_height);
|
||||
drawerargs.SetTextureUPos(texturefracx);
|
||||
drawerargs.SetTextureVPos(texelY);
|
||||
drawerargs.SetTextureVStep(texelStepY);
|
||||
drawerargs.DrawColumn(thread);
|
||||
}
|
||||
|
||||
static void DrawWallColumn8(RenderThread* thread, WallDrawerArgs& drawerargs, int x, int y1, int y2, uint32_t texelX, uint32_t texelY, uint32_t texelStepY, FSoftwareTexture* pic, int texwidth, int texheight, int fracbits, uint32_t uv_max)
|
||||
{
|
||||
texelY = (static_cast<uint64_t>(texelY)* texheight) >> (32 - fracbits);
|
||||
texelStepY = (static_cast<uint64_t>(texelStepY)* texheight) >> (32 - fracbits);
|
||||
|
||||
const uint8_t* pixels = pic->GetColumn(DefaultRenderStyle(), ((texelX >> 16)* texwidth) >> 16, nullptr);
|
||||
|
||||
drawerargs.SetTexture(pixels, nullptr, texheight);
|
||||
drawerargs.SetTextureVStep(texelStepY);
|
||||
|
||||
if (uv_max == 0 || texelStepY == 0) // power of two
|
||||
{
|
||||
int count = y2 - y1;
|
||||
|
||||
drawerargs.SetDest(thread->Viewport.get(), x, y1);
|
||||
drawerargs.SetCount(count);
|
||||
drawerargs.SetTextureVPos(texelY);
|
||||
drawerargs.DrawColumn(thread);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t left = y2 - y1;
|
||||
int y = y1;
|
||||
while (left > 0)
|
||||
{
|
||||
uint32_t available = uv_max - texelY;
|
||||
uint32_t next_uv_wrap = available / texelStepY;
|
||||
if (available % texelStepY != 0)
|
||||
next_uv_wrap++;
|
||||
uint32_t count = MIN(left, next_uv_wrap);
|
||||
|
||||
drawerargs.SetDest(thread->Viewport.get(), x, y);
|
||||
drawerargs.SetCount(count);
|
||||
drawerargs.SetTextureVPos(texelY);
|
||||
drawerargs.DrawColumn(thread);
|
||||
|
||||
y += count;
|
||||
left -= count;
|
||||
texelY += texelStepY * count;
|
||||
if (texelY >= uv_max)
|
||||
texelY -= uv_max;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderWallPart::ProcessNormalWall(const short* uwal, const short* dwal, const ProjectedWallTexcoords& texcoords)
|
||||
{
|
||||
CameraLight* cameraLight = CameraLight::Instance();
|
||||
|
@ -242,185 +137,55 @@ namespace swrenderer
|
|||
drawerargs.SetStyle(mask, additive, alpha, mLight.GetBaseColormap());
|
||||
}
|
||||
|
||||
bool fixed = (cameraLight->FixedColormap() || cameraLight->FixedLightLevel() >= 0);
|
||||
int count = x2 - x1;
|
||||
short* data = Thread->FrameMemory->AllocMemory<short>(count << 1);
|
||||
|
||||
bool haslights = r_dynlights && light_list;
|
||||
if (haslights)
|
||||
drawerargs.x1 = x1;
|
||||
drawerargs.x2 = x2;
|
||||
drawerargs.uwal = data - x1;
|
||||
drawerargs.dwal = data + count - x1; // to avoid calling AllocMemory twice
|
||||
memcpy(drawerargs.uwal + x1, uwal + x1, sizeof(short) * count);
|
||||
memcpy(drawerargs.dwal + x1, dwal + x1, sizeof(short) * count);
|
||||
drawerargs.WallC = WallC;
|
||||
drawerargs.texcoords = texcoords;
|
||||
|
||||
drawerargs.lightpos = mLight.GetLightPos(x1);
|
||||
drawerargs.lightstep = mLight.GetLightStep();
|
||||
drawerargs.mShade = LightVisibility::LightLevelToShade(mLight.GetLightLevel(), mLight.GetFoggy(), viewport);
|
||||
drawerargs.lightlist = light_list;
|
||||
|
||||
drawerargs.texwidth = pic->GetPhysicalWidth();
|
||||
drawerargs.texheight = pic->GetPhysicalHeight();
|
||||
if (viewport->RenderTarget->IsBgra())
|
||||
{
|
||||
float dx = WallC.tright.X - WallC.tleft.X;
|
||||
float dy = WallC.tright.Y - WallC.tleft.Y;
|
||||
float length = sqrt(dx * dx + dy * dy);
|
||||
drawerargs.dc_normal.X = dy / length;
|
||||
drawerargs.dc_normal.Y = -dx / length;
|
||||
drawerargs.dc_normal.Z = 0.0f;
|
||||
drawerargs.texpixels = pic->GetPixelsBgra();
|
||||
drawerargs.fracbits = 32;
|
||||
drawerargs.mipmapped = r_mipmap && pic->Mipmapped();
|
||||
}
|
||||
else
|
||||
{
|
||||
drawerargs.texpixels = pic->GetPixels(DefaultRenderStyle());
|
||||
int fracbits = 32 - pic->GetHeightBits();
|
||||
if (fracbits == 32) fracbits = 0; // One pixel tall textures
|
||||
drawerargs.fracbits = fracbits;
|
||||
drawerargs.mipmapped = false;
|
||||
}
|
||||
|
||||
int texwidth = pic->GetPhysicalWidth();
|
||||
int texheight = pic->GetPhysicalHeight();
|
||||
// This data really should be its own command as it rarely changes
|
||||
drawerargs.SetDest(viewport);
|
||||
drawerargs.CenterX = Thread->Viewport->CenterX;
|
||||
drawerargs.CenterY = Thread->Viewport->CenterY;
|
||||
drawerargs.FocalTangent = Thread->Viewport->viewwindow.FocalTangent;
|
||||
drawerargs.InvZtoScale = Thread->Viewport->InvZtoScale;
|
||||
drawerargs.ViewpointPos = { (float)Thread->Viewport->viewpoint.Pos.X, (float)Thread->Viewport->viewpoint.Pos.Y, (float)Thread->Viewport->viewpoint.Pos.Z };
|
||||
drawerargs.Sin = Thread->Viewport->viewpoint.Sin;
|
||||
drawerargs.Cos = Thread->Viewport->viewpoint.Cos;
|
||||
drawerargs.TanCos = Thread->Viewport->viewpoint.TanCos;
|
||||
drawerargs.TanSin = Thread->Viewport->viewpoint.TanSin;
|
||||
drawerargs.PortalMirrorFlags = Thread->Portal->MirrorFlags;
|
||||
drawerargs.fixedlight = (cameraLight->FixedColormap() || cameraLight->FixedLightLevel() >= 0);
|
||||
|
||||
int fracbits = 32 - pic->GetHeightBits();
|
||||
if (fracbits == 32) fracbits = 0; // One pixel tall textures
|
||||
if (viewport->RenderTarget->IsBgra()) fracbits = 32;
|
||||
drawerargs.SetTextureFracBits(fracbits);
|
||||
|
||||
uint32_t uv_max;
|
||||
int uv_fracbits = 32 - pic->GetHeightBits();
|
||||
if (uv_fracbits != 32)
|
||||
uv_max = texheight << uv_fracbits;
|
||||
|
||||
float curlight = mLight.GetLightPos(x1);
|
||||
float lightstep = mLight.GetLightStep();
|
||||
|
||||
float upos = texcoords.upos, ustepX = texcoords.ustepX, ustepY = texcoords.ustepY;
|
||||
float vpos = texcoords.vpos, vstepX = texcoords.vstepX, vstepY = texcoords.vstepY;
|
||||
float wpos = texcoords.wpos, wstepX = texcoords.wstepX, wstepY = texcoords.wstepY;
|
||||
float startX = texcoords.startX;
|
||||
|
||||
upos += ustepX * (x1 + 0.5f - startX);
|
||||
vpos += vstepX * (x1 + 0.5f - startX);
|
||||
wpos += wstepX * (x1 + 0.5f - startX);
|
||||
|
||||
float centerY = Thread->Viewport->CenterY;
|
||||
centerY -= 0.5f;
|
||||
|
||||
for (int x = x1; x < x2; x++)
|
||||
{
|
||||
int y1 = uwal[x];
|
||||
int y2 = dwal[x];
|
||||
if (y2 > y1)
|
||||
{
|
||||
if (!fixed) drawerargs.SetLight(curlight, mLight.GetLightLevel(), mLight.GetFoggy(), viewport);
|
||||
if (haslights)
|
||||
SetLights(drawerargs, x, y1);
|
||||
else
|
||||
drawerargs.dc_num_lights = 0;
|
||||
|
||||
float dy = (y1 - centerY);
|
||||
float u = upos + ustepY * dy;
|
||||
float v = vpos + vstepY * dy;
|
||||
float w = wpos + wstepY * dy;
|
||||
float scaleU = ustepX;
|
||||
float scaleV = vstepY;
|
||||
w = 1.0f / w;
|
||||
u *= w;
|
||||
v *= w;
|
||||
scaleU *= w;
|
||||
scaleV *= w;
|
||||
|
||||
uint32_t texelX = (uint32_t)(int64_t)((u - std::floor(u)) * 0x1'0000'0000LL);
|
||||
uint32_t texelY = (uint32_t)(int64_t)((v - std::floor(v)) * 0x1'0000'0000LL);
|
||||
uint32_t texelStepX = (uint32_t)(int64_t)(scaleU * 0x1'0000'0000LL);
|
||||
uint32_t texelStepY = (uint32_t)(int64_t)(scaleV * 0x1'0000'0000LL);
|
||||
|
||||
if (fracbits != 32)
|
||||
DrawWallColumn8(Thread, drawerargs, x, y1, y2, texelX, texelY, texelStepY, pic, texwidth, texheight, fracbits, uv_max);
|
||||
else
|
||||
DrawWallColumn32(Thread, drawerargs, x, y1, y2, texelX, texelY, texelStepX, texelStepY, pic, texwidth, texheight);
|
||||
}
|
||||
|
||||
upos += ustepX;
|
||||
vpos += vstepX;
|
||||
wpos += wstepX;
|
||||
curlight += lightstep;
|
||||
}
|
||||
|
||||
if (r_modelscene)
|
||||
{
|
||||
for (int x = x1; x < x2; x++)
|
||||
{
|
||||
int y1 = uwal[x];
|
||||
int y2 = dwal[x];
|
||||
if (y2 > y1)
|
||||
{
|
||||
int count = y2 - y1;
|
||||
|
||||
float w1 = 1.0f / WallC.sz1;
|
||||
float w2 = 1.0f / WallC.sz2;
|
||||
float t = (x - WallC.sx1 + 0.5f) / (WallC.sx2 - WallC.sx1);
|
||||
float wcol = w1 * (1.0f - t) + w2 * t;
|
||||
float zcol = 1.0f / wcol;
|
||||
float zbufferdepth = 1.0f / (zcol / viewport->viewwindow.FocalTangent);
|
||||
|
||||
drawerargs.SetDest(viewport, x, y1);
|
||||
drawerargs.SetCount(count);
|
||||
drawerargs.DrawDepthColumn(Thread, zbufferdepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderWallPart::SetLights(WallDrawerArgs &drawerargs, int x, int y1)
|
||||
{
|
||||
bool mirror = !!(Thread->Portal->MirrorFlags & RF_XFLIP);
|
||||
int tx = x;
|
||||
if (mirror)
|
||||
tx = viewwidth - tx - 1;
|
||||
|
||||
RenderViewport *viewport = Thread->Viewport.get();
|
||||
|
||||
// Find column position in view space
|
||||
float w1 = 1.0f / WallC.sz1;
|
||||
float w2 = 1.0f / WallC.sz2;
|
||||
float t = (x - WallC.sx1 + 0.5f) / (WallC.sx2 - WallC.sx1);
|
||||
float wcol = w1 * (1.0f - t) + w2 * t;
|
||||
float zcol = 1.0f / wcol;
|
||||
|
||||
drawerargs.dc_viewpos.X = (float)((tx + 0.5 - viewport->CenterX) / viewport->CenterX * zcol);
|
||||
drawerargs.dc_viewpos.Y = zcol;
|
||||
drawerargs.dc_viewpos.Z = (float)((viewport->CenterY - y1 - 0.5) / viewport->InvZtoScale * zcol);
|
||||
drawerargs.dc_viewpos_step.Z = (float)(-zcol / viewport->InvZtoScale);
|
||||
|
||||
// Calculate max lights that can touch column so we can allocate memory for the list
|
||||
int max_lights = 0;
|
||||
FLightNode *cur_node = light_list;
|
||||
while (cur_node)
|
||||
{
|
||||
if (cur_node->lightsource->IsActive())
|
||||
max_lights++;
|
||||
cur_node = cur_node->nextLight;
|
||||
}
|
||||
|
||||
drawerargs.dc_num_lights = 0;
|
||||
drawerargs.dc_lights = Thread->FrameMemory->AllocMemory<DrawerLight>(max_lights);
|
||||
|
||||
// Setup lights for column
|
||||
cur_node = light_list;
|
||||
while (cur_node)
|
||||
{
|
||||
if (cur_node->lightsource->IsActive())
|
||||
{
|
||||
double lightX = cur_node->lightsource->X() - viewport->viewpoint.Pos.X;
|
||||
double lightY = cur_node->lightsource->Y() - viewport->viewpoint.Pos.Y;
|
||||
double lightZ = cur_node->lightsource->Z() - viewport->viewpoint.Pos.Z;
|
||||
|
||||
float lx = (float)(lightX * viewport->viewpoint.Sin - lightY * viewport->viewpoint.Cos) - drawerargs.dc_viewpos.X;
|
||||
float ly = (float)(lightX * viewport->viewpoint.TanCos + lightY * viewport->viewpoint.TanSin) - drawerargs.dc_viewpos.Y;
|
||||
float lz = (float)lightZ;
|
||||
|
||||
// Precalculate the constant part of the dot here so the drawer doesn't have to.
|
||||
bool is_point_light = cur_node->lightsource->IsAttenuated();
|
||||
float lconstant = lx * lx + ly * ly;
|
||||
float nlconstant = is_point_light ? lx * drawerargs.dc_normal.X + ly * drawerargs.dc_normal.Y : 0.0f;
|
||||
|
||||
// Include light only if it touches this column
|
||||
float radius = cur_node->lightsource->GetRadius();
|
||||
if (radius * radius >= lconstant && nlconstant >= 0.0f)
|
||||
{
|
||||
uint32_t red = cur_node->lightsource->GetRed();
|
||||
uint32_t green = cur_node->lightsource->GetGreen();
|
||||
uint32_t blue = cur_node->lightsource->GetBlue();
|
||||
|
||||
auto &light = drawerargs.dc_lights[drawerargs.dc_num_lights++];
|
||||
light.x = lconstant;
|
||||
light.y = nlconstant;
|
||||
light.z = lz;
|
||||
light.radius = 256.0f / cur_node->lightsource->GetRadius();
|
||||
light.color = (red << 16) | (green << 8) | blue;
|
||||
}
|
||||
}
|
||||
|
||||
cur_node = cur_node->nextLight;
|
||||
}
|
||||
drawerargs.DrawWall(Thread);
|
||||
}
|
||||
|
||||
FLightNode* RenderWallPart::GetLightList()
|
||||
|
|
|
@ -62,7 +62,6 @@ namespace swrenderer
|
|||
private:
|
||||
void ProcessStripedWall(const short *uwal, const short *dwal, const ProjectedWallTexcoords& texcoords);
|
||||
void ProcessNormalWall(const short *uwal, const short *dwal, const ProjectedWallTexcoords& texcoords);
|
||||
void SetLights(WallDrawerArgs &drawerargs, int x, int y1);
|
||||
FLightNode* GetLightList();
|
||||
|
||||
RenderThread* Thread = nullptr;
|
||||
|
|
|
@ -38,6 +38,7 @@ namespace swrenderer
|
|||
|
||||
uint8_t *Colormap(RenderViewport *viewport) const;
|
||||
uint8_t *TranslationMap() const { return mTranslation; }
|
||||
FSWColormap* BaseColormap() const { return mBaseColormap; }
|
||||
|
||||
ShadeConstants ColormapConstants() const;
|
||||
fixed_t Light() const { return LIGHTSCALE(mLight, mShade); }
|
||||
|
|
|
@ -25,19 +25,12 @@
|
|||
|
||||
namespace swrenderer
|
||||
{
|
||||
void WallDrawerArgs::SetDest(RenderViewport *viewport, int x, int y)
|
||||
void WallDrawerArgs::SetDest(RenderViewport *viewport)
|
||||
{
|
||||
dc_viewport = viewport;
|
||||
dc_dest = viewport->GetDest(x, y);
|
||||
dc_dest_y = y;
|
||||
}
|
||||
|
||||
void WallDrawerArgs::DrawDepthColumn(RenderThread *thread, float idepth)
|
||||
{
|
||||
thread->Drawers(dc_viewport)->DrawDepthWallColumn(*this, idepth);
|
||||
}
|
||||
|
||||
void WallDrawerArgs::DrawColumn(RenderThread *thread)
|
||||
void WallDrawerArgs::DrawWall(RenderThread *thread)
|
||||
{
|
||||
(thread->Drawers(dc_viewport)->*wallfunc)(*this);
|
||||
}
|
||||
|
@ -48,7 +41,7 @@ namespace swrenderer
|
|||
{
|
||||
if (!additive)
|
||||
{
|
||||
wallfunc = &SWPixelFormatDrawers::DrawWallAddColumn;
|
||||
wallfunc = &SWPixelFormatDrawers::DrawWallAdd;
|
||||
dc_srcblend = Col2RGB8[alpha >> 10];
|
||||
dc_destblend = Col2RGB8[(OPAQUE - alpha) >> 10];
|
||||
dc_srcalpha = alpha;
|
||||
|
@ -56,7 +49,7 @@ namespace swrenderer
|
|||
}
|
||||
else
|
||||
{
|
||||
wallfunc = &SWPixelFormatDrawers::DrawWallAddClampColumn;
|
||||
wallfunc = &SWPixelFormatDrawers::DrawWallAddClamp;
|
||||
dc_srcblend = Col2RGB8_LessPrecision[alpha >> 10];
|
||||
dc_destblend = Col2RGB8_LessPrecision[FRACUNIT >> 10];
|
||||
dc_srcalpha = alpha;
|
||||
|
@ -65,11 +58,11 @@ namespace swrenderer
|
|||
}
|
||||
else if (masked)
|
||||
{
|
||||
wallfunc = &SWPixelFormatDrawers::DrawWallMaskedColumn;
|
||||
wallfunc = &SWPixelFormatDrawers::DrawWallMasked;
|
||||
}
|
||||
else
|
||||
{
|
||||
wallfunc = &SWPixelFormatDrawers::DrawWallColumn;
|
||||
wallfunc = &SWPixelFormatDrawers::DrawWall;
|
||||
}
|
||||
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "r_drawerargs.h"
|
||||
#include "swrenderer/line/r_wallsetup.h"
|
||||
|
||||
struct FSWColormap;
|
||||
struct FLightNode;
|
||||
|
@ -15,70 +16,52 @@ namespace swrenderer
|
|||
{
|
||||
public:
|
||||
void SetStyle(bool masked, bool additive, fixed_t alpha, FDynamicColormap *basecolormap);
|
||||
void SetDest(RenderViewport *viewport, int x, int y);
|
||||
void SetCount(int count) { dc_count = count; }
|
||||
void SetTexture(const uint8_t *pixels, const uint8_t *pixels2, int height)
|
||||
{
|
||||
dc_source = pixels;
|
||||
dc_source2 = pixels2;
|
||||
dc_textureheight = height;
|
||||
}
|
||||
void SetTextureFracBits(int bits) { dc_wall_fracbits = bits; }
|
||||
void SetTextureUPos(uint32_t pos) { dc_texturefracx = pos; }
|
||||
void SetTextureVPos(fixed_t pos) { dc_texturefrac = pos; }
|
||||
void SetTextureVStep(fixed_t step) { dc_iscale = step; }
|
||||
void SetDest(RenderViewport *viewport);
|
||||
void DrawWall(RenderThread *thread);
|
||||
|
||||
void DrawDepthColumn(RenderThread *thread, float idepth);
|
||||
void DrawColumn(RenderThread *thread);
|
||||
|
||||
uint8_t *Dest() const { return dc_dest; }
|
||||
int DestY() const { return dc_dest_y; }
|
||||
int Count() const { return dc_count; }
|
||||
|
||||
uint32_t *SrcBlend() const { return dc_srcblend; }
|
||||
uint32_t *DestBlend() const { return dc_destblend; }
|
||||
uint32_t* SrcBlend() const { return dc_srcblend; }
|
||||
uint32_t* DestBlend() const { return dc_destblend; }
|
||||
fixed_t SrcAlpha() const { return dc_srcalpha; }
|
||||
fixed_t DestAlpha() const { return dc_destalpha; }
|
||||
|
||||
uint32_t TextureUPos() const { return dc_texturefracx; }
|
||||
fixed_t TextureVPos() const { return dc_texturefrac; }
|
||||
fixed_t TextureVStep() const { return dc_iscale; }
|
||||
RenderViewport* Viewport() const { return dc_viewport; }
|
||||
|
||||
const uint8_t *TexturePixels() const { return dc_source; }
|
||||
const uint8_t *TexturePixels2() const { return dc_source2; }
|
||||
uint32_t TextureHeight() const { return dc_textureheight; }
|
||||
int x1, x2;
|
||||
short* uwal;
|
||||
short* dwal;
|
||||
FWallCoords WallC;
|
||||
ProjectedWallTexcoords texcoords;
|
||||
FLightNode* lightlist = nullptr;
|
||||
|
||||
int TextureFracBits() const { return dc_wall_fracbits; }
|
||||
float lightpos;
|
||||
float lightstep;
|
||||
int mShade;
|
||||
|
||||
FVector3 dc_normal = { 0,0,0 };
|
||||
FVector3 dc_viewpos = { 0,0,0 };
|
||||
FVector3 dc_viewpos_step = { 0,0,0 };
|
||||
DrawerLight *dc_lights = nullptr;
|
||||
int dc_num_lights = 0;
|
||||
int texwidth;
|
||||
int texheight;
|
||||
int fracbits;
|
||||
bool mipmapped;
|
||||
const void* texpixels;
|
||||
|
||||
RenderViewport *Viewport() const { return dc_viewport; }
|
||||
// Viewport data
|
||||
uint16_t PortalMirrorFlags;
|
||||
bool fixedlight;
|
||||
float CenterX;
|
||||
float CenterY;
|
||||
float FocalTangent;
|
||||
float InvZtoScale;
|
||||
FVector3 ViewpointPos;
|
||||
float Sin, Cos, TanCos, TanSin;
|
||||
|
||||
private:
|
||||
uint8_t *dc_dest = nullptr;
|
||||
int dc_dest_y = 0;
|
||||
int dc_count = 0;
|
||||
|
||||
fixed_t dc_iscale = 0;
|
||||
fixed_t dc_texturefrac = 0;
|
||||
uint32_t dc_texturefracx = 0;
|
||||
uint32_t dc_textureheight = 0;
|
||||
const uint8_t *dc_source = nullptr;
|
||||
const uint8_t *dc_source2 = nullptr;
|
||||
int dc_wall_fracbits = 0;
|
||||
|
||||
uint32_t *dc_srcblend = nullptr;
|
||||
uint32_t *dc_destblend = nullptr;
|
||||
fixed_t dc_srcalpha = 0;
|
||||
fixed_t dc_destalpha = 0;
|
||||
|
||||
typedef void(SWPixelFormatDrawers::*WallDrawerFunc)(const WallDrawerArgs &args);
|
||||
WallDrawerFunc wallfunc = nullptr;
|
||||
|
||||
RenderViewport *dc_viewport = nullptr;
|
||||
uint32_t* dc_srcblend = nullptr;
|
||||
uint32_t* dc_destblend = nullptr;
|
||||
fixed_t dc_srcalpha = 0;
|
||||
fixed_t dc_destalpha = 0;
|
||||
|
||||
RenderViewport* dc_viewport = nullptr;
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue