This commit is contained in:
Christoph Oelckers 2017-03-26 18:41:44 +02:00
commit 0cbbd8d4b1
34 changed files with 441 additions and 1042 deletions

View file

@ -872,7 +872,6 @@ set( POLYRENDER_SOURCES
polyrenderer/drawers/poly_draw_args.cpp
polyrenderer/drawers/screen_triangle.cpp
polyrenderer/math/tri_matrix.cpp
polyrenderer/math/poly_intersection.cpp
)
# These files will be flagged as "headers" so that they appear in project files

View file

@ -37,23 +37,23 @@
#include "poly_draw_args.h"
#include "swrenderer/viewport/r_viewport.h"
void PolyDrawArgs::SetClipPlane(float a, float b, float c, float d)
void PolyDrawArgs::SetClipPlane(const PolyClipPlane &plane)
{
clipPlane[0] = a;
clipPlane[1] = b;
clipPlane[2] = c;
clipPlane[3] = d;
mClipPlane[0] = plane.A;
mClipPlane[1] = plane.B;
mClipPlane[2] = plane.C;
mClipPlane[3] = plane.D;
}
void PolyDrawArgs::SetTexture(FTexture *texture)
{
textureWidth = texture->GetWidth();
textureHeight = texture->GetHeight();
mTextureWidth = texture->GetWidth();
mTextureHeight = texture->GetHeight();
if (PolyRenderer::Instance()->RenderTarget->IsBgra())
texturePixels = (const uint8_t *)texture->GetPixelsBgra();
mTexturePixels = (const uint8_t *)texture->GetPixelsBgra();
else
texturePixels = texture->GetPixels();
translation = nullptr;
mTexturePixels = texture->GetPixels();
mTranslation = nullptr;
}
void PolyDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, bool forcePal)
@ -64,22 +64,22 @@ void PolyDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, bool fo
if (table != nullptr && !table->Inactive)
{
if (PolyRenderer::Instance()->RenderTarget->IsBgra())
translation = (uint8_t*)table->Palette;
mTranslation = (uint8_t*)table->Palette;
else
translation = table->Remap;
mTranslation = table->Remap;
textureWidth = texture->GetWidth();
textureHeight = texture->GetHeight();
texturePixels = texture->GetPixels();
mTextureWidth = texture->GetWidth();
mTextureHeight = texture->GetHeight();
mTexturePixels = texture->GetPixels();
return;
}
}
if (forcePal)
{
textureWidth = texture->GetWidth();
textureHeight = texture->GetHeight();
texturePixels = texture->GetPixels();
mTextureWidth = texture->GetWidth();
mTextureHeight = texture->GetHeight();
mTexturePixels = texture->GetPixels();
}
else
{
@ -87,21 +87,48 @@ void PolyDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, bool fo
}
}
void PolyDrawArgs::SetColormap(FSWColormap *base_colormap)
void PolyDrawArgs::SetLight(FSWColormap *base_colormap, uint32_t lightlevel, double globVis, bool fixed)
{
uniforms.light_red = base_colormap->Color.r * 256 / 255;
uniforms.light_green = base_colormap->Color.g * 256 / 255;
uniforms.light_blue = base_colormap->Color.b * 256 / 255;
uniforms.light_alpha = base_colormap->Color.a * 256 / 255;
uniforms.fade_red = base_colormap->Fade.r;
uniforms.fade_green = base_colormap->Fade.g;
uniforms.fade_blue = base_colormap->Fade.b;
uniforms.fade_alpha = base_colormap->Fade.a;
uniforms.desaturate = MIN(abs(base_colormap->Desaturate), 255) * 255 / 256;
bool simple_shade = (base_colormap->Color.d == 0x00ffffff && base_colormap->Fade.d == 0x00000000 && base_colormap->Desaturate == 0);
if (simple_shade)
uniforms.flags |= TriUniforms::simple_shade;
else
uniforms.flags &= ~TriUniforms::simple_shade;
colormaps = base_colormap->Maps;
mGlobVis = (float)globVis;
PolyCameraLight *cameraLight = PolyCameraLight::Instance();
if (cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap())
{
lightlevel = cameraLight->FixedLightLevel() >= 0 ? cameraLight->FixedLightLevel() : 255;
fixed = true;
}
mLight = clamp<uint32_t>(lightlevel, 0, 255);
mFixedLight = fixed;
mLightRed = base_colormap->Color.r * 256 / 255;
mLightGreen = base_colormap->Color.g * 256 / 255;
mLightBlue = base_colormap->Color.b * 256 / 255;
mLightAlpha = base_colormap->Color.a * 256 / 255;
mFadeRed = base_colormap->Fade.r;
mFadeGreen = base_colormap->Fade.g;
mFadeBlue = base_colormap->Fade.b;
mFadeAlpha = base_colormap->Fade.a;
mDesaturate = MIN(abs(base_colormap->Desaturate), 255) * 255 / 256;
mSimpleShade = (base_colormap->Color.d == 0x00ffffff && base_colormap->Fade.d == 0x00000000 && base_colormap->Desaturate == 0);
mColormaps = base_colormap->Maps;
}
void PolyDrawArgs::SetColor(uint32_t bgra, uint8_t palindex)
{
if (PolyRenderer::Instance()->RenderTarget->IsBgra())
{
mColor = bgra;
}
else
{
mColor = palindex;
}
}
void PolyDrawArgs::DrawArray(const TriVertex *vertices, int vcount, PolyDrawMode mode)
{
mVertices = vertices;
mVertexCount = vcount;
mDrawMode = mode;
PolyRenderer::Instance()->DrawQueue->Push<DrawPolyTrianglesCommand>(*this, PolyTriangleDrawer::is_mirror());
}

View file

@ -27,43 +27,123 @@
#include "screen_triangle.h"
class FTexture;
struct TriMatrix;
enum class TriangleDrawMode
enum class PolyDrawMode
{
Normal,
Fan,
Strip
Triangles,
TriangleFan,
TriangleStrip
};
struct TriDrawTriangleArgs;
struct TriMatrix;
class PolyClipPlane
{
public:
PolyClipPlane() : A(0.0f), B(0.0f), C(0.0f), D(1.0f) { }
PolyClipPlane(float a, float b, float c, float d) : A(a), B(b), C(c), D(d) { }
float A, B, C, D;
};
class PolyDrawArgs
{
public:
TriUniforms uniforms;
const TriMatrix *objectToClip = nullptr;
const TriVertex *vinput = nullptr;
int vcount = 0;
TriangleDrawMode mode = TriangleDrawMode::Normal;
bool ccw = false;
// bool stencilTest = true; // Always true for now
bool subsectorTest = false;
bool writeStencil = true;
bool writeColor = true;
bool writeSubsector = true;
const uint8_t *texturePixels = nullptr;
int textureWidth = 0;
int textureHeight = 0;
const uint8_t *translation = nullptr;
uint8_t stenciltestvalue = 0;
uint8_t stencilwritevalue = 0;
const uint8_t *colormaps = nullptr;
float clipPlane[4];
TriBlendMode blendmode = TriBlendMode::Copy;
void SetClipPlane(float a, float b, float c, float d);
void SetClipPlane(const PolyClipPlane &plane);
void SetTexture(FTexture *texture);
void SetTexture(FTexture *texture, uint32_t translationID, bool forcePal = false);
void SetColormap(FSWColormap *base_colormap);
void SetLight(FSWColormap *basecolormap, uint32_t lightlevel, double globVis, bool fixed);
void SetSubsectorDepth(uint32_t subsectorDepth) { mSubsectorDepth = subsectorDepth; }
void SetSubsectorDepthTest(bool enable) { mSubsectorTest = enable; }
void SetStencilTestValue(uint8_t stencilTestValue) { mStencilTestValue = stencilTestValue; }
void SetWriteColor(bool enable) { mWriteColor = enable; }
void SetWriteStencil(bool enable, uint8_t stencilWriteValue = 0) { mWriteStencil = enable; mStencilWriteValue = stencilWriteValue; }
void SetWriteSubsectorDepth(bool enable) { mWriteSubsector = enable; }
void SetFaceCullCCW(bool counterclockwise) { mFaceCullCCW = counterclockwise; }
void SetStyle(TriBlendMode blendmode, double srcalpha = 1.0, double destalpha = 1.0) { mBlendMode = blendmode; mSrcAlpha = (uint32_t)(srcalpha * 256.0 + 0.5); mDestAlpha = (uint32_t)(destalpha * 256.0 + 0.5); }
void SetTransform(const TriMatrix *objectToClip) { mObjectToClip = objectToClip; }
void SetColor(uint32_t bgra, uint8_t palindex);
void DrawArray(const TriVertex *vertices, int vcount, PolyDrawMode mode = PolyDrawMode::Triangles);
const TriMatrix *ObjectToClip() const { return mObjectToClip; }
const float *ClipPlane() const { return mClipPlane; }
const TriVertex *Vertices() const { return mVertices; }
int VertexCount() const { return mVertexCount; }
PolyDrawMode DrawMode() const { return mDrawMode; }
bool FaceCullCCW() const { return mFaceCullCCW; }
bool WriteColor() const { return mWriteColor; }
const uint8_t *TexturePixels() const { return mTexturePixels; }
int TextureWidth() const { return mTextureWidth; }
int TextureHeight() const { return mTextureHeight; }
const uint8_t *Translation() const { return mTranslation; }
bool WriteStencil() const { return mWriteStencil; }
uint8_t StencilTestValue() const { return mStencilTestValue; }
uint8_t StencilWriteValue() const { return mStencilWriteValue; }
bool SubsectorTest() const { return mSubsectorTest; }
bool WriteSubsector() const { return mWriteSubsector; }
uint32_t SubsectorDepth() const { return mSubsectorDepth; }
TriBlendMode BlendMode() const { return mBlendMode; }
uint32_t Color() const { return mColor; }
uint32_t SrcAlpha() const { return mSrcAlpha; }
uint32_t DestAlpha() const { return mDestAlpha; }
float GlobVis() const { return mGlobVis; }
uint32_t Light() const { return mLight; }
const uint8_t *BaseColormap() const { return mColormaps; }
uint16_t ShadeLightAlpha() const { return mLightAlpha; }
uint16_t ShadeLightRed() const { return mLightRed; }
uint16_t ShadeLightGreen() const { return mLightGreen; }
uint16_t ShadeLightBlue() const { return mLightBlue; }
uint16_t ShadeFadeAlpha() const { return mFadeAlpha; }
uint16_t ShadeFadeRed() const { return mFadeRed; }
uint16_t ShadeFadeGreen() const { return mFadeGreen; }
uint16_t ShadeFadeBlue() const { return mFadeBlue; }
uint16_t ShadeDesaturate() const { return mDesaturate; }
bool SimpleShade() const { return mSimpleShade; }
bool NearestFilter() const { return mNearestFilter; }
bool FixedLight() const { return mFixedLight; }
private:
const TriMatrix *mObjectToClip = nullptr;
const TriVertex *mVertices = nullptr;
int mVertexCount = 0;
PolyDrawMode mDrawMode = PolyDrawMode::Triangles;
bool mFaceCullCCW = false;
bool mSubsectorTest = false;
bool mWriteStencil = true;
bool mWriteColor = true;
bool mWriteSubsector = true;
const uint8_t *mTexturePixels = nullptr;
int mTextureWidth = 0;
int mTextureHeight = 0;
const uint8_t *mTranslation = nullptr;
uint8_t mStencilTestValue = 0;
uint8_t mStencilWriteValue = 0;
const uint8_t *mColormaps = nullptr;
float mClipPlane[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
TriBlendMode mBlendMode = TriBlendMode::Copy;
uint32_t mLight = 0;
uint32_t mSubsectorDepth = 0;
uint32_t mColor = 0;
uint32_t mSrcAlpha = 0;
uint32_t mDestAlpha = 0;
uint16_t mLightAlpha = 0;
uint16_t mLightRed = 0;
uint16_t mLightGreen = 0;
uint16_t mLightBlue = 0;
uint16_t mFadeAlpha = 0;
uint16_t mFadeRed = 0;
uint16_t mFadeGreen = 0;
uint16_t mFadeBlue = 0;
uint16_t mDesaturate = 0;
float mGlobVis = 0.0f;
bool mSimpleShade = true;
bool mNearestFilter = true;
bool mFixedLight = false;
};

View file

@ -32,12 +32,11 @@ public:
{
using namespace TriScreenDrawerModes;
auto flags = args->uniforms->flags;
bool is_simple_shade = (flags & TriUniforms::simple_shade) == TriUniforms::simple_shade;
bool is_simple_shade = args->uniforms->SimpleShade();
if (SamplerT::Mode == (int)Samplers::Texture)
{
bool is_nearest_filter = (flags & TriUniforms::nearest_filter) == TriUniforms::nearest_filter;
bool is_nearest_filter = args->uniforms->NearestFilter();
if (is_simple_shade)
{
@ -79,11 +78,10 @@ public:
int startX = thread->StartX;
int startY = thread->StartY;
auto flags = args->uniforms->flags;
bool is_fixed_light = (flags & TriUniforms::fixed_light) == TriUniforms::fixed_light;
bool is_fixed_light = args->uniforms->FixedLight();
uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff;
uint32_t srcalpha = args->uniforms->srcalpha;
uint32_t destalpha = args->uniforms->destalpha;
uint32_t srcalpha = args->uniforms->SrcAlpha();
uint32_t destalpha = args->uniforms->DestAlpha();
// Calculate gradients
const TriVertex &v1 = *args->v1;
@ -107,16 +105,17 @@ public:
int pitch = args->pitch;
// Light
uint32_t light = args->uniforms->light;
float shade = (64.0f - (light * 255 / 256 + 12.0f) * 32.0f / 128.0f) / 32.0f;
float globVis = args->uniforms->globvis * (1.0f / 32.0f);
uint32_t light = args->uniforms->Light();
float shade = 2.0f - (light + 12.0f) / 128.0f;
float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f);
light += (light >> 7); // 255 -> 256
// Sampling stuff
uint32_t color = args->uniforms->color;
const uint32_t * RESTRICT translation = (const uint32_t *)args->translation;
const uint32_t * RESTRICT texPixels = (const uint32_t *)args->texturePixels;
uint32_t texWidth = args->textureWidth;
uint32_t texHeight = args->textureHeight;
uint32_t color = args->uniforms->Color();
const uint32_t * RESTRICT translation = (const uint32_t *)args->uniforms->Translation();
const uint32_t * RESTRICT texPixels = (const uint32_t *)args->uniforms->TexturePixels();
uint32_t texWidth = args->uniforms->TextureWidth();
uint32_t texHeight = args->uniforms->TextureHeight();
uint32_t oneU, oneV;
if (SamplerT::Mode != (int)Samplers::Fill)
{
@ -134,10 +133,10 @@ public:
int desaturate;
if (ShadeModeT::Mode == (int)ShadeMode::Advanced)
{
inv_desaturate = _mm_setr_epi16(256, 256 - args->uniforms->desaturate, 256 - args->uniforms->desaturate, 256 - args->uniforms->desaturate, 256, 256 - args->uniforms->desaturate, 256 - args->uniforms->desaturate, 256 - args->uniforms->desaturate);
shade_fade = _mm_set_epi16(args->uniforms->fade_alpha, args->uniforms->fade_red, args->uniforms->fade_green, args->uniforms->fade_blue, args->uniforms->fade_alpha, args->uniforms->fade_red, args->uniforms->fade_green, args->uniforms->fade_blue);
shade_light = _mm_set_epi16(args->uniforms->light_alpha, args->uniforms->light_red, args->uniforms->light_green, args->uniforms->light_blue, args->uniforms->light_alpha, args->uniforms->light_red, args->uniforms->light_green, args->uniforms->light_blue);
desaturate = args->uniforms->desaturate;
inv_desaturate = _mm_setr_epi16(256, 256 - args->uniforms->ShadeDesaturate(), 256 - args->uniforms->ShadeDesaturate(), 256 - args->uniforms->ShadeDesaturate(), 256, 256 - args->uniforms->ShadeDesaturate(), 256 - args->uniforms->ShadeDesaturate(), 256 - args->uniforms->ShadeDesaturate());
shade_fade = _mm_set_epi16(args->uniforms->ShadeFadeAlpha(), args->uniforms->ShadeFadeRed(), args->uniforms->ShadeFadeGreen(), args->uniforms->ShadeFadeBlue(), args->uniforms->ShadeFadeAlpha(), args->uniforms->ShadeFadeRed(), args->uniforms->ShadeFadeGreen(), args->uniforms->ShadeFadeBlue());
shade_light = _mm_set_epi16(args->uniforms->ShadeLightAlpha(), args->uniforms->ShadeLightRed(), args->uniforms->ShadeLightGreen(), args->uniforms->ShadeLightBlue(), args->uniforms->ShadeLightAlpha(), args->uniforms->ShadeLightRed(), args->uniforms->ShadeLightGreen(), args->uniforms->ShadeLightBlue());
desaturate = args->uniforms->ShadeDesaturate();
}
else
{

View file

@ -39,12 +39,11 @@ public:
int startX = thread->StartX;
int startY = thread->StartY;
auto flags = args->uniforms->flags;
bool is_fixed_light = (flags & TriUniforms::fixed_light) == TriUniforms::fixed_light;
bool is_fixed_light = args->uniforms->FixedLight();
uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff;
auto colormaps = args->colormaps;
uint32_t srcalpha = args->uniforms->srcalpha;
uint32_t destalpha = args->uniforms->destalpha;
auto colormaps = args->uniforms->BaseColormap();
uint32_t srcalpha = args->uniforms->SrcAlpha();
uint32_t destalpha = args->uniforms->DestAlpha();
// Calculate gradients
const TriVertex &v1 = *args->v1;
@ -68,16 +67,17 @@ public:
int pitch = args->pitch;
// Light
uint32_t light = args->uniforms->light;
float shade = (64.0f - (light * 255 / 256 + 12.0f) * 32.0f / 128.0f) / 32.0f;
float globVis = args->uniforms->globvis * (1.0f / 32.0f);
uint32_t light = args->uniforms->Light();
float shade = 2.0f - (light + 12.0f) / 128.0f;
float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f);
light += light >> 7; // 255 -> 256
// Sampling stuff
uint32_t color = args->uniforms->color;
const uint8_t * RESTRICT translation = args->translation;
const uint8_t * RESTRICT texPixels = args->texturePixels;
uint32_t texWidth = args->textureWidth;
uint32_t texHeight = args->textureHeight;
uint32_t color = args->uniforms->Color();
const uint8_t * RESTRICT translation = args->uniforms->Translation();
const uint8_t * RESTRICT texPixels = args->uniforms->TexturePixels();
uint32_t texWidth = args->uniforms->TextureWidth();
uint32_t texHeight = args->uniforms->TextureHeight();
for (int i = 0; i < numSpans; i++)
{

View file

@ -80,35 +80,35 @@ void PolyTriangleDrawer::toggle_mirror()
mirror = !mirror;
}
void PolyTriangleDrawer::draw(const PolyDrawArgs &args)
bool PolyTriangleDrawer::is_mirror()
{
PolyRenderer::Instance()->DrawQueue->Push<DrawPolyTrianglesCommand>(args, mirror);
return mirror;
}
void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, WorkerThreadData *thread)
{
if (drawargs.vcount < 3)
if (drawargs.VertexCount() < 3)
return;
PolyDrawFuncPtr drawfuncs[4];
int num_drawfuncs = 0;
drawfuncs[num_drawfuncs++] = drawargs.subsectorTest ? &ScreenTriangle::SetupSubsector : &ScreenTriangle::SetupNormal;
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;
int bmode = (int)drawargs.BlendMode();
if (drawargs.writeColor && drawargs.texturePixels)
if (drawargs.WriteColor() && drawargs.TexturePixels())
drawfuncs[num_drawfuncs++] = dest_bgra ? ScreenTriangle::TriDraw32[bmode] : ScreenTriangle::TriDraw8[bmode];
else if (drawargs.writeColor)
else if (drawargs.WriteColor())
drawfuncs[num_drawfuncs++] = dest_bgra ? ScreenTriangle::TriFill32[bmode] : ScreenTriangle::TriFill8[bmode];
}
if (drawargs.writeStencil)
if (drawargs.WriteStencil())
drawfuncs[num_drawfuncs++] = &ScreenTriangle::StencilWrite;
if (drawargs.writeSubsector)
if (drawargs.WriteSubsector())
drawfuncs[num_drawfuncs++] = &ScreenTriangle::SubsectorWrite;
TriDrawTriangleArgs args;
@ -118,53 +118,44 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, WorkerThreadD
args.clipright = dest_width;
args.cliptop = 0;
args.clipbottom = dest_height;
args.texturePixels = drawargs.texturePixels;
args.textureWidth = drawargs.textureWidth;
args.textureHeight = drawargs.textureHeight;
args.translation = drawargs.translation;
args.uniforms = &drawargs.uniforms;
args.stencilTestValue = drawargs.stenciltestvalue;
args.stencilWriteValue = drawargs.stencilwritevalue;
args.uniforms = &drawargs;
args.stencilPitch = PolyStencilBuffer::Instance()->BlockWidth();
args.stencilValues = PolyStencilBuffer::Instance()->Values();
args.stencilMasks = PolyStencilBuffer::Instance()->Masks();
args.subsectorGBuffer = PolySubsectorGBuffer::Instance()->Values();
args.colormaps = drawargs.colormaps;
args.RGB256k = RGB256k.All;
args.BaseColors = (const uint8_t *)GPalette.BaseColors;
bool ccw = drawargs.ccw;
const TriVertex *vinput = drawargs.vinput;
int vcount = drawargs.vcount;
bool ccw = drawargs.FaceCullCCW();
const TriVertex *vinput = drawargs.Vertices();
int vcount = drawargs.VertexCount();
ShadedTriVertex vert[3];
if (drawargs.mode == TriangleDrawMode::Normal)
if (drawargs.DrawMode() == PolyDrawMode::Triangles)
{
for (int i = 0; i < vcount / 3; i++)
{
for (int j = 0; j < 3; j++)
vert[j] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
vert[j] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++));
draw_shaded_triangle(vert, ccw, &args, thread, drawfuncs, num_drawfuncs);
}
}
else if (drawargs.mode == TriangleDrawMode::Fan)
else if (drawargs.DrawMode() == PolyDrawMode::TriangleFan)
{
vert[0] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
vert[1] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
vert[0] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++));
vert[1] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++));
for (int i = 2; i < vcount; i++)
{
vert[2] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
vert[2] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++));
draw_shaded_triangle(vert, ccw, &args, thread, drawfuncs, num_drawfuncs);
vert[1] = vert[2];
}
}
else // TriangleDrawMode::Strip
else // TriangleDrawMode::TriangleStrip
{
vert[0] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
vert[1] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
vert[0] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++));
vert[1] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++));
for (int i = 2; i < vcount; i++)
{
vert[2] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
vert[2] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++));
draw_shaded_triangle(vert, ccw, &args, thread, drawfuncs, num_drawfuncs);
vert[0] = vert[1];
vert[1] = vert[2];
@ -448,7 +439,7 @@ DrawPolyTrianglesCommand::DrawPolyTrianglesCommand(const PolyDrawArgs &args, boo
: args(args)
{
if (mirror)
this->args.ccw = !this->args.ccw;
this->args.SetFaceCullCCW(!this->args.FaceCullCCW());
}
void DrawPolyTrianglesCommand::Execute(DrawerThread *thread)
@ -461,32 +452,3 @@ void DrawPolyTrianglesCommand::Execute(DrawerThread *thread)
PolyTriangleDrawer::draw_arrays(args, &thread_data);
}
FString DrawPolyTrianglesCommand::DebugInfo()
{
FString blendmodestr;
switch (args.blendmode)
{
default: blendmodestr = "Unknown"; break;
case TriBlendMode::Copy: blendmodestr = "Copy"; break;
case TriBlendMode::AlphaBlend: blendmodestr = "AlphaBlend"; break;
case TriBlendMode::AddSolid: blendmodestr = "AddSolid"; break;
case TriBlendMode::Add: blendmodestr = "Add"; break;
case TriBlendMode::Sub: blendmodestr = "Sub"; break;
case TriBlendMode::RevSub: blendmodestr = "RevSub"; break;
case TriBlendMode::Stencil: blendmodestr = "Stencil"; break;
case TriBlendMode::Shaded: blendmodestr = "Shaded"; break;
case TriBlendMode::TranslateCopy: blendmodestr = "TranslateCopy"; break;
case TriBlendMode::TranslateAlphaBlend: blendmodestr = "TranslateAlphaBlend"; break;
case TriBlendMode::TranslateAdd: blendmodestr = "TranslateAdd"; break;
case TriBlendMode::TranslateSub: blendmodestr = "TranslateSub"; break;
case TriBlendMode::TranslateRevSub: blendmodestr = "TranslateRevSub"; break;
case TriBlendMode::AddSrcColorOneMinusSrcColor: blendmodestr = "AddSrcColorOneMinusSrcColor"; break;
}
FString info;
info.Format("DrawPolyTriangles: blend mode = %s, color = %d, light = %d, textureWidth = %d, textureHeight = %d, texture = %s, translation = %s, colormaps = %s",
blendmodestr.GetChars(), args.uniforms.color, args.uniforms.light, args.textureWidth, args.textureHeight,
args.texturePixels ? "ptr" : "null", args.translation ? "ptr" : "null", args.colormaps ? "ptr" : "null");
return info;
}

View file

@ -40,8 +40,8 @@ class PolyTriangleDrawer
{
public:
static void set_viewport(int x, int y, int width, int height, DCanvas *canvas);
static void draw(const PolyDrawArgs &args);
static void toggle_mirror();
static bool is_mirror();
private:
static ShadedTriVertex shade_vertex(const TriMatrix &objectToClip, const float *clipPlane, const TriVertex &v);
@ -66,7 +66,7 @@ public:
DrawPolyTrianglesCommand(const PolyDrawArgs &args, bool mirror);
void Execute(DrawerThread *thread) override;
FString DebugInfo() override;
FString DebugInfo() override { return "DrawPolyTriangles"; }
private:
PolyDrawArgs args;

View file

@ -52,7 +52,7 @@ void ScreenTriangle::SetupNormal(const TriDrawTriangleArgs *args, WorkerThreadDa
int stencilPitch = args->stencilPitch;
uint8_t * RESTRICT stencilValues = args->stencilValues;
uint32_t * RESTRICT stencilMasks = args->stencilMasks;
uint8_t stencilTestValue = args->stencilTestValue;
uint8_t stencilTestValue = args->uniforms->StencilTestValue();
TriFullSpan * RESTRICT span = thread->FullSpans;
TriPartialBlock * RESTRICT partial = thread->PartialBlocks;
@ -389,10 +389,10 @@ void ScreenTriangle::SetupSubsector(const TriDrawTriangleArgs *args, WorkerThrea
int stencilPitch = args->stencilPitch;
uint8_t * RESTRICT stencilValues = args->stencilValues;
uint32_t * RESTRICT stencilMasks = args->stencilMasks;
uint8_t stencilTestValue = args->stencilTestValue;
uint8_t stencilTestValue = args->uniforms->StencilTestValue();
uint32_t * RESTRICT subsectorGBuffer = args->subsectorGBuffer;
uint32_t subsectorDepth = args->uniforms->subsectorDepth;
uint32_t subsectorDepth = args->uniforms->SubsectorDepth();
int32_t pitch = args->pitch;
TriFullSpan * RESTRICT span = thread->FullSpans;
@ -800,7 +800,7 @@ void ScreenTriangle::StencilWrite(const TriDrawTriangleArgs *args, WorkerThreadD
{
uint8_t * RESTRICT stencilValues = args->stencilValues;
uint32_t * RESTRICT stencilMasks = args->stencilMasks;
uint32_t stencilWriteValue = args->stencilWriteValue;
uint32_t stencilWriteValue = args->uniforms->StencilWriteValue();
uint32_t stencilPitch = args->stencilPitch;
int numSpans = thread->NumFullSpans;
@ -869,7 +869,7 @@ void ScreenTriangle::StencilWrite(const TriDrawTriangleArgs *args, WorkerThreadD
void ScreenTriangle::SubsectorWrite(const TriDrawTriangleArgs *args, WorkerThreadData *thread)
{
uint32_t * RESTRICT subsectorGBuffer = args->subsectorGBuffer;
uint32_t subsectorDepth = args->uniforms->subsectorDepth;
uint32_t subsectorDepth = args->uniforms->SubsectorDepth();
int pitch = args->pitch;
int numSpans = thread->NumFullSpans;

View file

@ -26,6 +26,7 @@
#include <vector>
class FString;
class PolyDrawArgs;
struct TriFullSpan
{
@ -67,32 +68,6 @@ struct TriVertex
float varying[NumVarying];
};
struct TriUniforms
{
uint32_t light;
uint32_t subsectorDepth;
uint32_t color;
uint32_t srcalpha;
uint32_t destalpha;
uint16_t light_alpha;
uint16_t light_red;
uint16_t light_green;
uint16_t light_blue;
uint16_t fade_alpha;
uint16_t fade_red;
uint16_t fade_green;
uint16_t fade_blue;
uint16_t desaturate;
float globvis;
uint32_t flags;
enum Flags
{
simple_shade = 1,
nearest_filter = 2,
fixed_light = 4
};
};
struct TriDrawTriangleArgs
{
uint8_t *dest;
@ -104,20 +79,11 @@ struct TriDrawTriangleArgs
int32_t clipright;
int32_t cliptop;
int32_t clipbottom;
const uint8_t *texturePixels;
uint32_t textureWidth;
uint32_t textureHeight;
const uint8_t *translation;
const TriUniforms *uniforms;
uint8_t *stencilValues;
uint32_t *stencilMasks;
int32_t stencilPitch;
uint8_t stencilTestValue;
uint8_t stencilWriteValue;
uint32_t *subsectorGBuffer;
const uint8_t *colormaps;
const uint8_t *RGB256k;
const uint8_t *BaseColors;
const PolyDrawArgs *uniforms;
};
enum class TriBlendMode

View file

@ -1,235 +0,0 @@
/*
** Various 3D intersection tests
** Copyright (c) 1997-2015 The UICore Team
**
** This software is provided 'as-is', without any express or implied
** warranty. In no event will the authors be held liable for any damages
** arising from the use of this software.
**
** Permission is granted to anyone to use this software for any purpose,
** including commercial applications, and to alter it and redistribute it
** freely, subject to the following restrictions:
**
** 1. The origin of this software must not be misrepresented; you must not
** claim that you wrote the original software. If you use this software
** in a product, an acknowledgment in the product documentation would be
** appreciated but is not required.
** 2. Altered source versions must be plainly marked as such, and must not be
** misrepresented as being the original software.
** 3. This notice may not be removed or altered from any source distribution.
**
*/
#include <stdlib.h>
#include "templates.h"
#include "doomdef.h"
#include "poly_intersection.h"
IntersectionTest::Result IntersectionTest::plane_aabb(const Vec4f &plane, const AxisAlignedBoundingBox &aabb)
{
Vec3f center = aabb.center();
Vec3f extents = aabb.extents();
float e = extents.x * std::abs(plane.x) + extents.y * std::abs(plane.y) + extents.z * std::abs(plane.z);
float s = center.x * plane.x + center.y * plane.y + center.z * plane.z + plane.w;
if (s - e > 0)
return inside;
else if (s + e < 0)
return outside;
else
return intersecting;
}
IntersectionTest::Result IntersectionTest::plane_obb(const Vec4f &plane, const OrientedBoundingBox &obb)
{
Vec3f n(plane);
float d = plane.w;
float e = obb.extents.x * std::abs(Vec3f::dot(obb.axis_x, n)) + obb.extents.y * std::abs(Vec3f::dot(obb.axis_y, n)) + obb.extents.z * std::abs(Vec3f::dot(obb.axis_z, n));
float s = Vec3f::dot(obb.center, n) + d;
if (s - e > 0)
return inside;
else if (s + e < 0)
return outside;
else
return intersecting;
}
IntersectionTest::OverlapResult IntersectionTest::sphere(const Vec3f &center1, float radius1, const Vec3f &center2, float radius2)
{
Vec3f h = center1 - center2;
float square_distance = Vec3f::dot(h, h);
float radius_sum = radius1 + radius2;
if (square_distance > radius_sum * radius_sum)
return disjoint;
else
return overlap;
}
IntersectionTest::OverlapResult IntersectionTest::sphere_aabb(const Vec3f &center, float radius, const AxisAlignedBoundingBox &aabb)
{
Vec3f a = aabb.aabb_min - center;
Vec3f b = center - aabb.aabb_max;
a.x = std::max(a.x, 0.0f);
a.y = std::max(a.y, 0.0f);
a.z = std::max(a.z, 0.0f);
b.x = std::max(b.x, 0.0f);
b.y = std::max(b.y, 0.0f);
b.z = std::max(b.z, 0.0f);
Vec3f e = a + b;
float d = Vec3f::dot(e, e);
if (d > radius * radius)
return disjoint;
else
return overlap;
}
IntersectionTest::OverlapResult IntersectionTest::aabb(const AxisAlignedBoundingBox &a, const AxisAlignedBoundingBox &b)
{
if (a.aabb_min.x > b.aabb_max.x || b.aabb_min.x > a.aabb_max.x ||
a.aabb_min.y > b.aabb_max.y || b.aabb_min.y > a.aabb_max.y ||
a.aabb_min.z > b.aabb_max.z || b.aabb_min.z > a.aabb_max.z)
{
return disjoint;
}
else
{
return overlap;
}
}
IntersectionTest::Result IntersectionTest::frustum_aabb(const FrustumPlanes &frustum, const AxisAlignedBoundingBox &box)
{
bool is_intersecting = false;
for (int i = 0; i < 6; i++)
{
Result result = plane_aabb(frustum.planes[i], box);
if (result == outside)
return outside;
else if (result == intersecting)
is_intersecting = true;
break;
}
if (is_intersecting)
return intersecting;
else
return inside;
}
IntersectionTest::Result IntersectionTest::frustum_obb(const FrustumPlanes &frustum, const OrientedBoundingBox &box)
{
bool is_intersecting = false;
for (int i = 0; i < 6; i++)
{
Result result = plane_obb(frustum.planes[i], box);
if (result == outside)
return outside;
else if (result == intersecting)
is_intersecting = true;
}
if (is_intersecting)
return intersecting;
else
return inside;
}
IntersectionTest::OverlapResult IntersectionTest::ray_aabb(const Vec3f &ray_start, const Vec3f &ray_end, const AxisAlignedBoundingBox &aabb)
{
Vec3f c = (ray_start + ray_end) * 0.5f;
Vec3f w = ray_end - c;
Vec3f h = aabb.extents();
c -= aabb.center();
Vec3f v(std::abs(w.x), std::abs(w.y), std::abs(w.z));
if (std::abs(c.x) > v.x + h.x || std::abs(c.y) > v.y + h.y || std::abs(c.z) > v.z + h.z)
return disjoint;
if (std::abs(c.y * w.z - c.z * w.y) > h.y * v.z + h.z * v.y ||
std::abs(c.x * w.z - c.z * w.x) > h.x * v.z + h.z * v.x ||
std::abs(c.x * w.y - c.y * w.x) > h.x * v.y + h.y * v.x)
return disjoint;
return overlap;
}
/////////////////////////////////////////////////////////////////////////////
FrustumPlanes::FrustumPlanes()
{
}
FrustumPlanes::FrustumPlanes(const Mat4f &world_to_projection)
{
planes[0] = near_frustum_plane(world_to_projection);
planes[1] = far_frustum_plane(world_to_projection);
planes[2] = left_frustum_plane(world_to_projection);
planes[3] = right_frustum_plane(world_to_projection);
planes[4] = top_frustum_plane(world_to_projection);
planes[5] = bottom_frustum_plane(world_to_projection);
}
Vec4f FrustumPlanes::left_frustum_plane(const Mat4f &m)
{
Vec4f plane(
m.matrix[3 + 0 * 4] + m.matrix[0 + 0 * 4],
m.matrix[3 + 1 * 4] + m.matrix[0 + 1 * 4],
m.matrix[3 + 2 * 4] + m.matrix[0 + 2 * 4],
m.matrix[3 + 3 * 4] + m.matrix[0 + 3 * 4]);
plane /= plane.length3();
return plane;
}
Vec4f FrustumPlanes::right_frustum_plane(const Mat4f &m)
{
Vec4f plane(
m.matrix[3 + 0 * 4] - m.matrix[0 + 0 * 4],
m.matrix[3 + 1 * 4] - m.matrix[0 + 1 * 4],
m.matrix[3 + 2 * 4] - m.matrix[0 + 2 * 4],
m.matrix[3 + 3 * 4] - m.matrix[0 + 3 * 4]);
plane /= plane.length3();
return plane;
}
Vec4f FrustumPlanes::top_frustum_plane(const Mat4f &m)
{
Vec4f plane(
m.matrix[3 + 0 * 4] - m.matrix[1 + 0 * 4],
m.matrix[3 + 1 * 4] - m.matrix[1 + 1 * 4],
m.matrix[3 + 2 * 4] - m.matrix[1 + 2 * 4],
m.matrix[3 + 3 * 4] - m.matrix[1 + 3 * 4]);
plane /= plane.length3();
return plane;
}
Vec4f FrustumPlanes::bottom_frustum_plane(const Mat4f &m)
{
Vec4f plane(
m.matrix[3 + 0 * 4] + m.matrix[1 + 0 * 4],
m.matrix[3 + 1 * 4] + m.matrix[1 + 1 * 4],
m.matrix[3 + 2 * 4] + m.matrix[1 + 2 * 4],
m.matrix[3 + 3 * 4] + m.matrix[1 + 3 * 4]);
plane /= plane.length3();
return plane;
}
Vec4f FrustumPlanes::near_frustum_plane(const Mat4f &m)
{
Vec4f plane(
m.matrix[3 + 0 * 4] + m.matrix[2 + 0 * 4],
m.matrix[3 + 1 * 4] + m.matrix[2 + 1 * 4],
m.matrix[3 + 2 * 4] + m.matrix[2 + 2 * 4],
m.matrix[3 + 3 * 4] + m.matrix[2 + 3 * 4]);
plane /= plane.length3();
return plane;
}
Vec4f FrustumPlanes::far_frustum_plane(const Mat4f &m)
{
Vec4f plane(
m.matrix[3 + 0 * 4] - m.matrix[2 + 0 * 4],
m.matrix[3 + 1 * 4] - m.matrix[2 + 1 * 4],
m.matrix[3 + 2 * 4] - m.matrix[2 + 2 * 4],
m.matrix[3 + 3 * 4] - m.matrix[2 + 3 * 4]);
plane /= plane.length3();
return plane;
}

View file

@ -1,179 +0,0 @@
/*
** Various 3D intersection tests
** Copyright (c) 1997-2015 The UICore Team
**
** This software is provided 'as-is', without any express or implied
** warranty. In no event will the authors be held liable for any damages
** arising from the use of this software.
**
** Permission is granted to anyone to use this software for any purpose,
** including commercial applications, and to alter it and redistribute it
** freely, subject to the following restrictions:
**
** 1. The origin of this software must not be misrepresented; you must not
** claim that you wrote the original software. If you use this software
** in a product, an acknowledgment in the product documentation would be
** appreciated but is not required.
** 2. Altered source versions must be plainly marked as such, and must not be
** misrepresented as being the original software.
** 3. This notice may not be removed or altered from any source distribution.
**
*/
#pragma once
#include "polyrenderer/drawers/poly_triangle.h"
#include <algorithm>
#include <cmath>
class Vec3f;
class Vec4f
{
public:
Vec4f() = default;
Vec4f(const Vec4f &) = default;
Vec4f(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { }
Vec4f(float v) : x(v), y(v), z(v), w(v) { }
Vec4f(const Vec3f &xyz, float w);
static float dot(const Vec4f &a, const Vec4f &b) { return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; }
static float dot3(const Vec4f &a, const Vec4f &b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
float length3() const { return std::sqrt(dot3(*this, *this)); }
float magnitude() const { return std::sqrt(dot(*this, *this)); }
Vec4f &operator+=(const Vec4f &b) { *this = Vec4f(x + b.x, y + b.y, z + b.z, w + b.w); return *this; }
Vec4f &operator-=(const Vec4f &b) { *this = Vec4f(x - b.x, y - b.y, z - b.z, w - b.w); return *this; }
Vec4f &operator*=(const Vec4f &b) { *this = Vec4f(x * b.x, y * b.y, z * b.z, w * b.w); return *this; }
Vec4f &operator/=(const Vec4f &b) { *this = Vec4f(x / b.x, y / b.y, z / b.z, w / b.w); return *this; }
Vec4f &operator+=(float b) { *this = Vec4f(x + b, y + b, z + b, w + b); return *this; }
Vec4f &operator-=(float b) { *this = Vec4f(x - b, y - b, z - b, w - b); return *this; }
Vec4f &operator*=(float b) { *this = Vec4f(x * b, y * b, z * b, w * b); return *this; }
Vec4f &operator/=(float b) { *this = Vec4f(x / b, y / b, z / b, w / b); return *this; }
float x, y, z, w;
};
inline bool operator==(const Vec4f &a, const Vec4f &b) { return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w; }
inline bool operator!=(const Vec4f &a, const Vec4f &b) { return a.x != b.x || a.y != b.y || a.z != b.z || a.w == b.w; }
class Vec3f
{
public:
Vec3f() = default;
Vec3f(const Vec3f &) = default;
Vec3f(const Vec4f &v) : x(v.x), y(v.y), z(v.z) { }
Vec3f(float x, float y, float z) : x(x), y(y), z(z) { }
Vec3f(float v) : x(v), y(v), z(v) { }
static float dot(const Vec3f &a, const Vec3f &b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
float length() const { return std::sqrt(dot(*this, *this)); }
Vec3f &operator+=(const Vec3f &b) { *this = Vec3f(x + b.x, y + b.y, z + b.z); return *this; }
Vec3f &operator-=(const Vec3f &b) { *this = Vec3f(x - b.x, y - b.y, z - b.z); return *this; }
Vec3f &operator*=(const Vec3f &b) { *this = Vec3f(x * b.x, y * b.y, z * b.z); return *this; }
Vec3f &operator/=(const Vec3f &b) { *this = Vec3f(x / b.x, y / b.y, z / b.z); return *this; }
Vec3f &operator+=(float b) { *this = Vec3f(x + b, y + b, z + b); return *this; }
Vec3f &operator-=(float b) { *this = Vec3f(x - b, y - b, z - b); return *this; }
Vec3f &operator*=(float b) { *this = Vec3f(x * b, y * b, z * b); return *this; }
Vec3f &operator/=(float b) { *this = Vec3f(x / b, y / b, z / b); return *this; }
float x, y, z;
};
inline bool operator==(const Vec3f &a, const Vec3f &b) { return a.x == b.x && a.y == b.y && a.z == b.z; }
inline bool operator!=(const Vec3f &a, const Vec3f &b) { return a.x != b.x || a.y != b.y || a.z != b.z; }
inline Vec3f operator+(const Vec3f &a, const Vec3f &b) { return Vec3f(a.x + b.x, a.y + b.y, a.z + b.z); }
inline Vec3f operator-(const Vec3f &a, const Vec3f &b) { return Vec3f(a.x - b.x, a.y - b.y, a.z - b.z); }
inline Vec3f operator*(const Vec3f &a, const Vec3f &b) { return Vec3f(a.x * b.x, a.y * b.y, a.z * b.z); }
inline Vec3f operator/(const Vec3f &a, const Vec3f &b) { return Vec3f(a.x / b.x, a.y / b.y, a.z / b.z); }
inline Vec3f operator+(const Vec3f &a, float b) { return Vec3f(a.x + b, a.y + b, a.z + b); }
inline Vec3f operator-(const Vec3f &a, float b) { return Vec3f(a.x - b, a.y - b, a.z - b); }
inline Vec3f operator*(const Vec3f &a, float b) { return Vec3f(a.x * b, a.y * b, a.z * b); }
inline Vec3f operator/(const Vec3f &a, float b) { return Vec3f(a.x / b, a.y / b, a.z / b); }
inline Vec3f operator+(float a, const Vec3f &b) { return Vec3f(a + b.x, a + b.y, a + b.z); }
inline Vec3f operator-(float a, const Vec3f &b) { return Vec3f(a - b.x, a - b.y, a - b.z); }
inline Vec3f operator*(float a, const Vec3f &b) { return Vec3f(a * b.x, a * b.y, a * b.z); }
inline Vec3f operator/(float a, const Vec3f &b) { return Vec3f(a / b.x, a / b.y, a / b.z); }
inline Vec4f::Vec4f(const Vec3f &xyz, float w) : x(xyz.x), y(xyz.y), z(xyz.z), w(w) { }
typedef TriMatrix Mat4f;
class AxisAlignedBoundingBox
{
public:
AxisAlignedBoundingBox() : aabb_min(), aabb_max() {}
AxisAlignedBoundingBox(const Vec3f &aabb_min, const Vec3f &aabb_max) : aabb_min(aabb_min), aabb_max(aabb_max) { }
AxisAlignedBoundingBox(const AxisAlignedBoundingBox &aabb, const Vec3f &barycentric_min, const Vec3f &barycentric_max)
: aabb_min(mix(aabb.aabb_min, aabb.aabb_max, barycentric_min)), aabb_max(mix(aabb.aabb_min, aabb.aabb_max, barycentric_max)) { }
Vec3f center() const { return (aabb_max + aabb_min) * 0.5f; }
Vec3f extents() const { return (aabb_max - aabb_min) * 0.5f; }
Vec3f aabb_min;
Vec3f aabb_max;
private:
template<typename A, typename B, typename C>
inline A mix(A a, B b, C mix)
{
return a * (C(1) - mix) + b * mix;
}
};
class OrientedBoundingBox
{
public:
Vec3f center;
Vec3f extents;
Vec3f axis_x;
Vec3f axis_y;
Vec3f axis_z;
};
class FrustumPlanes
{
public:
FrustumPlanes();
explicit FrustumPlanes(const Mat4f &world_to_projection);
Vec4f planes[6];
private:
static Vec4f left_frustum_plane(const Mat4f &matrix);
static Vec4f right_frustum_plane(const Mat4f &matrix);
static Vec4f top_frustum_plane(const Mat4f &matrix);
static Vec4f bottom_frustum_plane(const Mat4f &matrix);
static Vec4f near_frustum_plane(const Mat4f &matrix);
static Vec4f far_frustum_plane(const Mat4f &matrix);
};
class IntersectionTest
{
public:
enum Result
{
outside,
inside,
intersecting,
};
enum OverlapResult
{
disjoint,
overlap
};
static Result plane_aabb(const Vec4f &plane, const AxisAlignedBoundingBox &aabb);
static Result plane_obb(const Vec4f &plane, const OrientedBoundingBox &obb);
static OverlapResult sphere(const Vec3f &center1, float radius1, const Vec3f &center2, float radius2);
static OverlapResult sphere_aabb(const Vec3f &center, float radius, const AxisAlignedBoundingBox &aabb);
static OverlapResult aabb(const AxisAlignedBoundingBox &a, const AxisAlignedBoundingBox &b);
static Result frustum_aabb(const FrustumPlanes &frustum, const AxisAlignedBoundingBox &box);
static Result frustum_obb(const FrustumPlanes &frustum, const OrientedBoundingBox &box);
static OverlapResult ray_aabb(const Vec3f &ray_start, const Vec3f &ray_end, const AxisAlignedBoundingBox &box);
};

View file

@ -3,7 +3,6 @@
#include "drawers/poly_draw_args.cpp"
#include "drawers/poly_triangle.cpp"
#include "drawers/screen_triangle.cpp"
#include "math/poly_intersection.cpp"
#include "math/tri_matrix.cpp"
#include "scene/poly_cull.cpp"
#include "scene/poly_decal.cpp"

View file

@ -134,7 +134,7 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines)
ClearBuffers();
SetSceneViewport();
SetupPerspectiveMatrix();
MainPortal.SetViewpoint(WorldToClip, Vec4f(0.0f, 0.0f, 0.0f, 1.0f), GetNextStencilValue());
MainPortal.SetViewpoint(WorldToClip, PolyClipPlane(0.0f, 0.0f, 0.0f, 1.0f), GetNextStencilValue());
MainPortal.Render(0);
Skydome.Render(WorldToClip);
MainPortal.RenderTranslucent(0);

View file

@ -28,10 +28,9 @@
#include "poly_cull.h"
#include "polyrenderer/poly_renderer.h"
void PolyCull::CullScene(const TriMatrix &worldToClip, const Vec4f &portalClipPlane)
void PolyCull::CullScene(const TriMatrix &worldToClip, const PolyClipPlane &portalClipPlane)
{
PvsSectors.clear();
frustumPlanes = FrustumPlanes(worldToClip);
PortalClipPlane = portalClipPlane;
// Cull front to back
@ -210,20 +209,6 @@ int PolyCull::PointOnSide(const DVector2 &pos, const node_t *node)
bool PolyCull::CheckBBox(float *bspcoord)
{
#if 0 // This doesn't work because it creates gaps in the angle based clipper segment list :(
// Start using a quick frustum AABB test:
AxisAlignedBoundingBox aabb(Vec3f(bspcoord[BOXLEFT], bspcoord[BOXBOTTOM], (float)PolyRenderer::Instance()->Viewpoint.Pos.Z - 1000.0f), Vec3f(bspcoord[BOXRIGHT], bspcoord[BOXTOP], (float)PolyRenderer::Instance()->Viewpoint.Pos.Z + 1000.0f));
auto result = IntersectionTest::frustum_aabb(frustumPlanes, aabb);
if (result == IntersectionTest::outside)
return false;
// Skip if its in front of the portal:
if (IntersectionTest::plane_aabb(PortalClipPlane, aabb) == IntersectionTest::outside)
return false;
#endif
// Occlusion test using solid segments:
static const uint8_t checkcoord[12][4] =
{

View file

@ -23,13 +23,12 @@
#pragma once
#include "polyrenderer/drawers/poly_triangle.h"
#include "polyrenderer/math/poly_intersection.h"
class PolyCull
{
public:
void ClearSolidSegments();
void CullScene(const TriMatrix &worldToClip, const Vec4f &portalClipPlane);
void CullScene(const TriMatrix &worldToClip, const PolyClipPlane &portalClipPlane);
bool GetAnglesForLine(double x1, double y1, double x2, double y2, angle_t &angle1, angle_t &angle2) const;
void MarkSegmentCulled(angle_t angle1, angle_t angle2);
@ -61,8 +60,7 @@ private:
const int SolidCullScale = 3000;
bool FirstSkyHeight = true;
FrustumPlanes frustumPlanes;
Vec4f PortalClipPlane;
PolyClipPlane PortalClipPlane;
static angle_t PointToPseudoAngle(double x, double y);
static angle_t AngleToPseudo(angle_t ang);

View file

@ -31,7 +31,7 @@
#include "a_sharedglobal.h"
#include "swrenderer/scene/r_scene.h"
void RenderPolyDecal::RenderWallDecals(const TriMatrix &worldToClip, const Vec4f &clipPlane, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue)
void RenderPolyDecal::RenderWallDecals(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue)
{
if (line->linedef == nullptr && line->sidedef == nullptr)
return;
@ -43,7 +43,7 @@ void RenderPolyDecal::RenderWallDecals(const TriMatrix &worldToClip, const Vec4f
}
}
void RenderPolyDecal::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue)
void RenderPolyDecal::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue)
{
if (decal->RenderFlags & RF_INVISIBLE || !viewactive || !decal->PicNum.isValid())
return;
@ -130,49 +130,21 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan
}
bool fullbrightSprite = (decal->RenderFlags & RF_FULLBRIGHT) == RF_FULLBRIGHT;
PolyCameraLight *cameraLight = PolyCameraLight::Instance();
int lightlevel = fullbrightSprite ? 255 : front->lightlevel + actualextralight;
PolyDrawArgs args;
args.uniforms.flags = TriUniforms::nearest_filter;
args.SetColormap(GetColorTable(front->Colormap));
args.SetLight(GetColorTable(front->Colormap), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), fullbrightSprite);
args.SetTexture(tex, decal->Translation, true);
args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy);
if (fullbrightSprite || cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap())
{
args.uniforms.light = 256;
args.uniforms.flags |= TriUniforms::fixed_light;
}
else
{
args.uniforms.light = (uint32_t)((front->lightlevel + actualextralight) / 255.0f * 256.0f);
}
args.uniforms.subsectorDepth = subsectorDepth;
if (PolyRenderer::Instance()->RenderTarget->IsBgra())
{
args.uniforms.color = 0xff000000 | decal->AlphaColor;
}
else
{
args.uniforms.color = ((uint32_t)decal->AlphaColor) >> 24;
}
args.uniforms.srcalpha = (uint32_t)(decal->Alpha * 256.0 + 0.5);
args.uniforms.destalpha = 256 - args.uniforms.srcalpha;
args.objectToClip = &worldToClip;
args.vinput = vertices;
args.vcount = 4;
args.mode = TriangleDrawMode::Fan;
args.ccw = true;
args.stenciltestvalue = stencilValue;
args.stencilwritevalue = stencilValue;
//mode = R_SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor);
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
args.blendmode = TriBlendMode::Shaded;
args.subsectorTest = true;
args.writeStencil = false;
args.writeSubsector = false;
PolyTriangleDrawer::draw(args);
args.SetSubsectorDepth(subsectorDepth);
args.SetColor(0xff000000 | decal->AlphaColor, decal->AlphaColor >> 24);
args.SetStyle(TriBlendMode::Shaded, decal->Alpha, 1.0 - decal->Alpha); // R_SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor);
args.SetTransform(&worldToClip);
args.SetFaceCullCCW(true);
args.SetStencilTestValue(stencilValue);
args.SetWriteStencil(true, stencilValue);
args.SetClipPlane(clipPlane);
args.SetSubsectorDepthTest(true);
args.SetWriteStencil(false);
args.SetWriteSubsectorDepth(false);
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
}

View file

@ -24,13 +24,11 @@
#include "polyrenderer/drawers/poly_triangle.h"
class Vec4f;
class RenderPolyDecal
{
public:
static void RenderWallDecals(const TriMatrix &worldToClip, const Vec4f &clipPlane, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue);
static void RenderWallDecals(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue);
private:
void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue);
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue);
};

View file

@ -25,6 +25,7 @@
#include "doomdef.h"
#include "sbar.h"
#include "poly_light.h"
#include "polyrenderer/poly_renderer.h"
fixed_t PolyLightVisibility::LightLevelToShade(int lightlevel, bool foggy)
{
@ -41,3 +42,8 @@ fixed_t PolyLightVisibility::LightLevelToShade(int lightlevel, bool foggy)
return (NUMCOLORMAPS * 2 * FRACUNIT) - ((lightlevel + 12) * (FRACUNIT*NUMCOLORMAPS / 128));
}
}
double PolyLightVisibility::FocalTangent()
{
return PolyRenderer::Instance()->Viewwindow.FocalTangent;
}

View file

@ -31,9 +31,9 @@ typedef swrenderer::CameraLight PolyCameraLight;
class PolyLightVisibility
{
public:
double WallGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : WallVisibility; }
double SpriteGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : WallVisibility; }
double ParticleGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : (WallVisibility * 0.5); }
double WallGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : WallVisibility / FocalTangent(); }
double SpriteGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : WallVisibility / FocalTangent(); }
double ParticleGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : WallVisibility * 0.5 / FocalTangent(); }
// The vis value to pass into the GETPALOOKUP or LIGHTSCALE macros
double WallVis(double screenZ, bool foggy) const { return WallGlobVis(foggy) / screenZ; }
@ -43,6 +43,8 @@ public:
static fixed_t LightLevelToShade(int lightlevel, bool foggy);
private:
static double FocalTangent();
// 1706 is the value for walls on 1080p 16:9 displays.
double WallVisibility = 1706.0;
bool NoLightFade = false;

View file

@ -29,7 +29,7 @@
#include "polyrenderer/poly_renderer.h"
#include "polyrenderer/scene/poly_light.h"
void RenderPolyParticle::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue)
void RenderPolyParticle::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue)
{
DVector3 pos = particle->Pos;
double psize = particle->size / 8.0;
@ -68,51 +68,20 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, const Vec4f &clipP
vertices[i].varying[1] = (float)(1.0f - offsets[i].second);
}
// int color = (particle->color >> 24) & 0xff; // pal index, I think
bool fullbrightSprite = particle->bright != 0;
PolyCameraLight *cameraLight = PolyCameraLight::Instance();
int lightlevel = fullbrightSprite ? 255 : sub->sector->lightlevel + actualextralight;
PolyDrawArgs args;
args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.ParticleGlobVis(foggy);
if (fullbrightSprite || cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap())
{
args.uniforms.light = 256;
args.uniforms.flags = TriUniforms::fixed_light | TriUniforms::nearest_filter;
}
else
{
args.uniforms.light = (uint32_t)((sub->sector->lightlevel + actualextralight) / 255.0f * 256.0f);
args.uniforms.flags = TriUniforms::nearest_filter;
}
args.uniforms.subsectorDepth = subsectorDepth;
uint32_t alpha = (uint32_t)clamp(particle->alpha * 255.0f + 0.5f, 0.0f, 255.0f);
if (PolyRenderer::Instance()->RenderTarget->IsBgra())
{
args.uniforms.color = (alpha << 24) | (particle->color & 0xffffff);
}
else
{
args.uniforms.color = ((uint32_t)particle->color) >> 24;
args.uniforms.srcalpha = alpha;
args.uniforms.destalpha = 255 - alpha;
}
args.objectToClip = &worldToClip;
args.vinput = vertices;
args.vcount = 4;
args.mode = TriangleDrawMode::Fan;
args.ccw = true;
args.stenciltestvalue = stencilValue;
args.stencilwritevalue = stencilValue;
args.SetColormap(GetColorTable(sub->sector->Colormap));
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
args.subsectorTest = true;
args.writeStencil = false;
args.writeSubsector = false;
args.blendmode = TriBlendMode::AlphaBlend;
PolyTriangleDrawer::draw(args);
args.SetLight(GetColorTable(sub->sector->Colormap), lightlevel, PolyRenderer::Instance()->Light.ParticleGlobVis(foggy), fullbrightSprite);
args.SetSubsectorDepth(subsectorDepth);
args.SetSubsectorDepthTest(true);
args.SetColor(particle->color | 0xff000000, particle->color >> 24);
args.SetStyle(TriBlendMode::AlphaBlend, particle->alpha, 1.0 - particle->alpha);
args.SetTransform(&worldToClip);
args.SetFaceCullCCW(true);
args.SetStencilTestValue(stencilValue);
args.SetWriteStencil(false);
args.SetWriteSubsectorDepth(false);
args.SetClipPlane(clipPlane);
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
}

View file

@ -25,10 +25,8 @@
#include "polyrenderer/drawers/poly_triangle.h"
#include "p_effect.h"
class Vec4f;
class RenderPolyParticle
{
public:
void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue);
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue);
};

View file

@ -33,7 +33,7 @@
EXTERN_CVAR(Int, r_3dfloors)
void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals)
void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals)
{
RenderPolyPlane plane;
@ -91,7 +91,7 @@ void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const Vec4f &cl
plane.Render(worldToClip, clipPlane, cull, sub, subsectorDepth, stencilValue, false, skyFloorHeight, sectorPortals);
}
void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakeFloor)
void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakeFloor)
{
FTextureID picnum = ceiling ? *fakeFloor->bottom.texture : *fakeFloor->top.texture;
FTexture *tex = TexMan(picnum);
@ -111,16 +111,7 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const Vec4f &c
UVTransform xform(ceiling ? fakeFloor->top.model->planes[sector_t::ceiling].xform : fakeFloor->top.model->planes[sector_t::floor].xform, tex);
PolyDrawArgs args;
args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy); // .SlopePlaneGlobVis(foggy) * 48.0f;
args.uniforms.light = (uint32_t)(lightlevel / 255.0f * 256.0f);
if (cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap())
args.uniforms.light = 256;
args.uniforms.flags = TriUniforms::nearest_filter;
args.uniforms.subsectorDepth = subsectorDepth;
TriVertex *vertices = PolyRenderer::Instance()->FrameMemory.AllocMemory<TriVertex>(sub->numlines);
if (ceiling)
{
for (uint32_t i = 0; i < sub->numlines; i++)
@ -138,21 +129,20 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const Vec4f &c
}
}
args.objectToClip = &worldToClip;
args.vinput = vertices;
args.vcount = sub->numlines;
args.mode = TriangleDrawMode::Fan;
args.ccw = true;
args.stenciltestvalue = stencilValue;
args.stencilwritevalue = stencilValue + 1;
PolyDrawArgs args;
args.SetLight(GetColorTable(sub->sector->Colormap), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), false);
args.SetSubsectorDepth(subsectorDepth);
args.SetTransform(&worldToClip);
args.SetStyle(TriBlendMode::Copy);
args.SetFaceCullCCW(true);
args.SetStencilTestValue(stencilValue);
args.SetWriteStencil(true, stencilValue + 1);
args.SetTexture(tex);
args.SetColormap(GetColorTable(sub->sector->Colormap));
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
args.blendmode = TriBlendMode::Copy;
PolyTriangleDrawer::draw(args);
args.SetClipPlane(clipPlane);
args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan);
}
void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals)
void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals)
{
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
bool foggy = false;
@ -291,16 +281,6 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan
UVTransform transform(ceiling ? frontsector->planes[sector_t::ceiling].xform : frontsector->planes[sector_t::floor].xform, tex);
PolyCameraLight *cameraLight = PolyCameraLight::Instance();
PolyDrawArgs args;
args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy);// ->SlopePlaneGlobVis(foggy) * 48.0f;
args.uniforms.light = (uint32_t)(frontsector->lightlevel / 255.0f * 256.0f);
if (cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap())
args.uniforms.light = 256;
args.uniforms.flags = TriUniforms::nearest_filter;
args.uniforms.subsectorDepth = isSky ? RenderPolyScene::SkySubsectorDepth : subsectorDepth;
TriVertex *vertices = PolyRenderer::Instance()->FrameMemory.AllocMemory<TriVertex>(sub->numlines);
if (ceiling)
@ -320,37 +300,36 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan
}
}
args.objectToClip = &worldToClip;
args.vinput = vertices;
args.vcount = sub->numlines;
args.mode = TriangleDrawMode::Fan;
args.ccw = ccw;
args.stenciltestvalue = stencilValue;
args.stencilwritevalue = stencilValue + 1;
args.SetColormap(GetColorTable(frontsector->Colormap, frontsector->SpecialColors[ceiling]));
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
PolyDrawArgs args;
args.SetLight(GetColorTable(frontsector->Colormap, frontsector->SpecialColors[ceiling]), frontsector->lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), false);
args.SetSubsectorDepth(isSky ? RenderPolyScene::SkySubsectorDepth : subsectorDepth);
args.SetTransform(&worldToClip);
args.SetFaceCullCCW(ccw);
args.SetStencilTestValue(stencilValue);
args.SetWriteStencil(true, stencilValue + 1);
args.SetClipPlane(clipPlane);
if (!isSky)
{
args.SetTexture(tex);
args.blendmode = TriBlendMode::Copy;
PolyTriangleDrawer::draw(args);
args.SetStyle(TriBlendMode::Copy);
args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan);
}
else
{
if (portal)
{
args.stencilwritevalue = polyportal->StencilValue;
polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, subsectorDepth });
args.SetWriteStencil(true, polyportal->StencilValue);
polyportal->Shape.push_back({ vertices, (int)sub->numlines, ccw, subsectorDepth });
}
else
{
args.stencilwritevalue = 255;
args.SetWriteStencil(true, 255);
}
args.writeColor = false;
args.writeSubsector = false;
PolyTriangleDrawer::draw(args);
args.SetWriteColor(false);
args.SetWriteSubsectorDepth(false);
args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan);
for (uint32_t i = 0; i < sub->numlines; i++)
{
@ -414,13 +393,11 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan
wallvert[3] = PlaneVertex(line->v1, skyHeight, transform);
}
args.vinput = wallvert;
args.vcount = 4;
PolyTriangleDrawer::draw(args);
args.DrawArray(wallvert, 4, PolyDrawMode::TriangleFan);
if (portal)
{
polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, subsectorDepth });
polyportal->Shape.push_back({ wallvert, 4, ccw, subsectorDepth });
}
}
}

View file

@ -26,12 +26,11 @@
class PolyDrawSectorPortal;
class PolyCull;
class Vec4f;
class RenderPolyPlane
{
public:
static void RenderPlanes(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals);
static void RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals);
private:
struct UVTransform
@ -48,7 +47,7 @@ private:
float xOffs, yOffs;
};
void Render3DFloor(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakefloor);
void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals);
void Render3DFloor(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakefloor);
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals);
TriVertex PlaneVertex(vertex_t *v1, double height, const UVTransform &transform);
};

View file

@ -45,7 +45,7 @@ void PolyDrawSectorPortal::Render(int portalDepth)
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
Vec4f portalPlane = Vec4f(0.0f);
PolyClipPlane portalPlane(0.0f, 0.0f, 0.0f, 1.0f);
if (Portal->mType != PORTS_SKYVIEWPOINT)
{
float minHeight;
@ -71,17 +71,11 @@ void PolyDrawSectorPortal::Render(int portalDepth)
if (!first && minHeight > viewpoint.Pos.Z)
{
portalPlane.x = 0.0f;
portalPlane.y = 0.0f;
portalPlane.z = 1.0f;
portalPlane.w = -minHeight;
portalPlane = PolyClipPlane(0.0f, 0.0f, 1.0f, -minHeight);
}
else if (!first && maxHeight < viewpoint.Pos.Z)
{
portalPlane.x = 0.0f;
portalPlane.y = 0.0f;
portalPlane.z = -1.0f;
portalPlane.w = maxHeight;
portalPlane = PolyClipPlane(0.0f, 0.0f, -1.0f, maxHeight);
}
}
@ -223,7 +217,7 @@ void PolyDrawLinePortal::Render(int portalDepth)
DVector2 planeNormal = (clipLine->v2->fPos() - clipLine->v1->fPos()).Rotated90CW();
planeNormal.MakeUnit();
double planeD = -(planeNormal | (planePos + planeNormal * 0.001));
Vec4f portalPlane((float)planeNormal.X, (float)planeNormal.Y, 0.0f, (float)planeD);
PolyClipPlane portalPlane((float)planeNormal.X, (float)planeNormal.Y, (float)0.0f, (float)planeD);
RenderPortal.SetViewpoint(worldToClip, portalPlane, StencilValue);
RenderPortal.SetPortalSegments(Segments);

View file

@ -43,7 +43,7 @@ RenderPolyScene::~RenderPolyScene()
{
}
void RenderPolyScene::SetViewpoint(const TriMatrix &worldToClip, const Vec4f &portalPlane, uint32_t stencilValue)
void RenderPolyScene::SetViewpoint(const TriMatrix &worldToClip, const PolyClipPlane &portalPlane, uint32_t stencilValue)
{
WorldToClip = worldToClip;
StencilValue = stencilValue;
@ -249,40 +249,33 @@ void RenderPolyScene::RenderPortals(int portalDepth)
else // Fill with black
{
PolyDrawArgs args;
args.objectToClip = &WorldToClip;
args.mode = TriangleDrawMode::Fan;
args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy);
args.uniforms.color = 0;
args.uniforms.light = 256;
args.uniforms.flags = TriUniforms::fixed_light;
args.SetClipPlane(PortalPlane.x, PortalPlane.y, PortalPlane.z, PortalPlane.w);
args.SetTransform(&WorldToClip);
args.SetLight(&NormalLight, 255, PolyRenderer::Instance()->Light.WallGlobVis(foggy), true);
args.SetColor(0, 0);
args.SetClipPlane(PortalPlane);
args.SetStyle(TriBlendMode::Copy);
for (auto &portal : SectorPortals)
{
args.stenciltestvalue = portal->StencilValue;
args.stencilwritevalue = portal->StencilValue + 1;
args.SetStencilTestValue(portal->StencilValue);
args.SetWriteStencil(true, portal->StencilValue + 1);
for (const auto &verts : portal->Shape)
{
args.vinput = verts.Vertices;
args.vcount = verts.Count;
args.ccw = verts.Ccw;
args.uniforms.subsectorDepth = verts.SubsectorDepth;
args.blendmode = TriBlendMode::Copy;
PolyTriangleDrawer::draw(args);
args.SetFaceCullCCW(verts.Ccw);
args.SetSubsectorDepth(verts.SubsectorDepth);
args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
}
}
for (auto &portal : LinePortals)
{
args.stenciltestvalue = portal->StencilValue;
args.stencilwritevalue = portal->StencilValue + 1;
args.SetStencilTestValue(portal->StencilValue);
args.SetWriteStencil(true, portal->StencilValue + 1);
for (const auto &verts : portal->Shape)
{
args.vinput = verts.Vertices;
args.vcount = verts.Count;
args.ccw = verts.Ccw;
args.uniforms.subsectorDepth = verts.SubsectorDepth;
PolyTriangleDrawer::draw(args);
args.SetFaceCullCCW(verts.Ccw);
args.SetSubsectorDepth(verts.SubsectorDepth);
args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
}
}
}
@ -298,19 +291,16 @@ void RenderPolyScene::RenderTranslucent(int portalDepth)
portal->RenderTranslucent(portalDepth + 1);
PolyDrawArgs args;
args.objectToClip = &WorldToClip;
args.mode = TriangleDrawMode::Fan;
args.stenciltestvalue = portal->StencilValue + 1;
args.stencilwritevalue = StencilValue + 1;
args.SetClipPlane(PortalPlane.x, PortalPlane.y, PortalPlane.z, PortalPlane.w);
args.SetTransform(&WorldToClip);
args.SetStencilTestValue(portal->StencilValue + 1);
args.SetWriteStencil(true, StencilValue + 1);
args.SetClipPlane(PortalPlane);
for (const auto &verts : portal->Shape)
{
args.vinput = verts.Vertices;
args.vcount = verts.Count;
args.ccw = verts.Ccw;
args.uniforms.subsectorDepth = verts.SubsectorDepth;
args.writeColor = false;
PolyTriangleDrawer::draw(args);
args.SetFaceCullCCW(verts.Ccw);
args.SetSubsectorDepth(verts.SubsectorDepth);
args.SetWriteColor(false);
args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
}
}
@ -320,19 +310,16 @@ void RenderPolyScene::RenderTranslucent(int portalDepth)
portal->RenderTranslucent(portalDepth + 1);
PolyDrawArgs args;
args.objectToClip = &WorldToClip;
args.mode = TriangleDrawMode::Fan;
args.stenciltestvalue = portal->StencilValue + 1;
args.stencilwritevalue = StencilValue + 1;
args.SetClipPlane(PortalPlane.x, PortalPlane.y, PortalPlane.z, PortalPlane.w);
args.SetTransform(&WorldToClip);
args.SetStencilTestValue(portal->StencilValue + 1);
args.SetWriteStencil(true, StencilValue + 1);
args.SetClipPlane(PortalPlane);
for (const auto &verts : portal->Shape)
{
args.vinput = verts.Vertices;
args.vcount = verts.Count;
args.ccw = verts.Ccw;
args.uniforms.subsectorDepth = verts.SubsectorDepth;
args.writeColor = false;
PolyTriangleDrawer::draw(args);
args.SetFaceCullCCW(verts.Ccw);
args.SetSubsectorDepth(verts.SubsectorDepth);
args.SetWriteColor(false);
args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
}
}
}

View file

@ -29,7 +29,6 @@
#include "doomdata.h"
#include "r_utility.h"
#include "polyrenderer/drawers/poly_triangle.h"
#include "polyrenderer/math/poly_intersection.h"
#include "poly_wall.h"
#include "poly_sprite.h"
#include "poly_wallsprite.h"
@ -74,7 +73,7 @@ class RenderPolyScene
public:
RenderPolyScene();
~RenderPolyScene();
void SetViewpoint(const TriMatrix &worldToClip, const Vec4f &portalPlane, uint32_t stencilValue);
void SetViewpoint(const TriMatrix &worldToClip, const PolyClipPlane &portalPlane, uint32_t stencilValue);
void SetPortalSegments(const std::vector<PolyPortalSegment> &segments);
void Render(int portalDepth);
void RenderTranslucent(int portalDepth);
@ -91,7 +90,7 @@ private:
void RenderSprite(AActor *thing, double sortDistance, DVector2 left, DVector2 right, double t1, double t2, void *node);
TriMatrix WorldToClip;
Vec4f PortalPlane;
PolyClipPlane PortalPlane;
uint32_t StencilValue = 0;
PolyCull Cull;
uint32_t NextSubsectorDepth = 0;

View file

@ -38,7 +38,6 @@ PolySkyDome::PolySkyDome()
void PolySkyDome::Render(const TriMatrix &worldToClip)
{
FTextureID sky1tex, sky2tex;
bool foggy = false;
if ((level.flags & LEVEL_SWAPSKIES) && !(level.flags & LEVEL_DOUBLESKY))
sky1tex = sky2texture;
else
@ -57,15 +56,12 @@ void PolySkyDome::Render(const TriMatrix &worldToClip)
int rc = mRows + 1;
PolyDrawArgs args;
args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy);
args.uniforms.light = 256;
args.uniforms.flags = TriUniforms::nearest_filter;
args.uniforms.subsectorDepth = RenderPolyScene::SkySubsectorDepth;
args.objectToClip = &objectToClip;
args.stenciltestvalue = 255;
args.stencilwritevalue = 1;
args.SetColormap(&NormalLight);
args.SetClipPlane(0.0f, 0.0f, 0.0f, 0.0f);
args.SetLight(&NormalLight, 255, PolyRenderer::Instance()->Light.WallGlobVis(false), true);
args.SetSubsectorDepth(RenderPolyScene::SkySubsectorDepth);
args.SetTransform(&objectToClip);
args.SetStencilTestValue(255);
args.SetWriteStencil(true, 1);
args.SetClipPlane(PolyClipPlane(0.0f, 0.0f, 0.0f, 1.0f));
RenderCapColorRow(args, frontskytex, 0, false);
RenderCapColorRow(args, frontskytex, rc, true);
@ -84,28 +80,21 @@ void PolySkyDome::Render(const TriMatrix &worldToClip)
void PolySkyDome::RenderRow(PolyDrawArgs &args, int row, uint32_t capcolor)
{
args.vinput = &mVertices[mPrimStart[row]];
args.vcount = mPrimStart[row + 1] - mPrimStart[row];
args.mode = TriangleDrawMode::Strip;
args.ccw = false;
args.uniforms.color = capcolor;
args.blendmode = TriBlendMode::Skycap;
PolyTriangleDrawer::draw(args);
args.SetFaceCullCCW(false);
args.SetColor(capcolor, 0);
args.SetStyle(TriBlendMode::Skycap);
args.DrawArray(&mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], PolyDrawMode::TriangleStrip);
}
void PolySkyDome::RenderCapColorRow(PolyDrawArgs &args, FTexture *skytex, int row, bool bottomCap)
{
uint32_t solid = skytex->GetSkyCapColor(bottomCap);
if (!PolyRenderer::Instance()->RenderTarget->IsBgra())
solid = RGB32k.RGB[(RPART(solid) >> 3)][(GPART(solid) >> 3)][(BPART(solid) >> 3)];
uint8_t palsolid = RGB32k.RGB[(RPART(solid) >> 3)][(GPART(solid) >> 3)][(BPART(solid) >> 3)];
args.vinput = &mVertices[mPrimStart[row]];
args.vcount = mPrimStart[row + 1] - mPrimStart[row];
args.mode = TriangleDrawMode::Fan;
args.ccw = bottomCap;
args.uniforms.color = solid;
args.blendmode = TriBlendMode::Copy;
PolyTriangleDrawer::draw(args);
args.SetFaceCullCCW(bottomCap);
args.SetColor(solid, palsolid);
args.SetStyle(TriBlendMode::Copy);
args.DrawArray(&mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], PolyDrawMode::TriangleFan);
}
void PolySkyDome::CreateDome()

View file

@ -27,7 +27,6 @@
#include "r_data/r_translate.h"
#include "poly_sprite.h"
#include "polyrenderer/poly_renderer.h"
#include "polyrenderer/math/poly_intersection.h"
#include "polyrenderer/scene/poly_light.h"
EXTERN_CVAR(Float, transsouls)
@ -65,7 +64,7 @@ bool RenderPolySprite::GetLine(AActor *thing, DVector2 &left, DVector2 &right)
return true;
}
void RenderPolySprite::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, float t1, float t2)
void RenderPolySprite::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, float t1, float t2)
{
DVector2 line[2];
if (!GetLine(thing, line[0], line[1]))
@ -136,136 +135,80 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, const Vec4f &clipPla
}
bool fullbrightSprite = ((thing->renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT));
PolyCameraLight *cameraLight = PolyCameraLight::Instance();
int lightlevel = fullbrightSprite ? 255 : thing->Sector->lightlevel + actualextralight;
PolyDrawArgs args;
args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.SpriteGlobVis(foggy);
args.uniforms.flags = TriUniforms::nearest_filter;
if (fullbrightSprite || cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap())
{
args.uniforms.light = 256;
args.uniforms.flags |= TriUniforms::fixed_light;
}
else
{
args.uniforms.light = (uint32_t)((thing->Sector->lightlevel + actualextralight) / 255.0f * 256.0f);
}
args.uniforms.subsectorDepth = subsectorDepth;
args.objectToClip = &worldToClip;
args.vinput = vertices;
args.vcount = 4;
args.mode = TriangleDrawMode::Fan;
args.ccw = true;
args.stenciltestvalue = stencilValue;
args.stencilwritevalue = stencilValue;
args.SetLight(GetColorTable(sub->sector->Colormap, sub->sector->SpecialColors[sector_t::sprites], true), lightlevel, PolyRenderer::Instance()->Light.SpriteGlobVis(foggy), fullbrightSprite);
args.SetSubsectorDepth(subsectorDepth);
args.SetTransform(&worldToClip);
args.SetFaceCullCCW(true);
args.SetStencilTestValue(stencilValue);
args.SetWriteStencil(true, stencilValue);
args.SetTexture(tex, thing->Translation);
args.SetColormap(GetColorTable(sub->sector->Colormap, sub->sector->SpecialColors[sector_t::sprites], true));
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
args.SetClipPlane(clipPlane);
TriBlendMode blendmode;
if (thing->RenderStyle == LegacyRenderStyles[STYLE_Normal] ||
(r_drawfuzz == 0 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy]))
{
args.uniforms.destalpha = 0;
args.uniforms.srcalpha = 256;
blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add;
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, 1.0, 0.0);
}
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Add] && fullbrightSprite && thing->Alpha == 1.0 && args.translation == nullptr)
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Add] && fullbrightSprite && thing->Alpha == 1.0 && !args.Translation())
{
args.uniforms.destalpha = 256;
args.uniforms.srcalpha = 256;
blendmode = TriBlendMode::AddSrcColorOneMinusSrcColor;
args.SetStyle(TriBlendMode::AddSrcColorOneMinusSrcColor, 1.0, 1.0);
}
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Add])
{
args.uniforms.destalpha = (uint32_t)(1.0 * 256);
args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256);
blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add;
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, thing->Alpha, 1.0);
}
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Subtract])
{
args.uniforms.destalpha = (uint32_t)(1.0 * 256);
args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256);
blendmode = args.translation ? TriBlendMode::TranslateRevSub : TriBlendMode::RevSub;
args.SetStyle(args.Translation() ? TriBlendMode::TranslateRevSub : TriBlendMode::RevSub, thing->Alpha, 1.0);
}
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_SoulTrans])
{
args.uniforms.destalpha = (uint32_t)(256 - transsouls * 256);
args.uniforms.srcalpha = (uint32_t)(transsouls * 256);
blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add;
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, transsouls, 1.0 - transsouls);
}
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Fuzzy] ||
(r_drawfuzz == 2 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy]))
{ // NYI - Fuzzy - for now, just a copy of "Shadow"
args.uniforms.destalpha = 160;
args.uniforms.srcalpha = 0;
blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add;
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, 0.0, 160 / 255.0);
}
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Shadow] ||
(r_drawfuzz == 1 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy]))
{
args.uniforms.destalpha = 160;
args.uniforms.srcalpha = 0;
blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add;
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, 0.0, 160 / 255.0);
}
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_TranslucentStencil])
{
args.uniforms.destalpha = (uint32_t)(256 - thing->Alpha * 256);
args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256);
args.uniforms.color = 0xff000000 | thing->fillcolor;
blendmode = TriBlendMode::Stencil;
args.SetColor(0xff000000 | thing->fillcolor, thing->fillcolor >> 24);
args.SetStyle(TriBlendMode::Stencil, thing->Alpha, 1.0 - thing->Alpha);
}
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_AddStencil])
{
args.uniforms.destalpha = 256;
args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256);
args.uniforms.color = 0xff000000 | thing->fillcolor;
blendmode = TriBlendMode::Stencil;
args.SetColor(0xff000000 | thing->fillcolor, thing->fillcolor >> 24);
args.SetStyle(TriBlendMode::Stencil, thing->Alpha, 1.0 - thing->Alpha);
}
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Shaded])
{
args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256);
args.uniforms.destalpha = 256 - args.uniforms.srcalpha;
args.uniforms.color = 0;
blendmode = TriBlendMode::Shaded;
args.SetColor(0, 0);
args.SetStyle(TriBlendMode::Shaded, thing->Alpha, 1.0 - thing->Alpha);
args.SetTexture(tex, thing->Translation, true);
}
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_AddShaded])
{
args.uniforms.destalpha = 256;
args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256);
args.uniforms.color = 0;
blendmode = TriBlendMode::Shaded;
args.SetColor(0, 0);
args.SetStyle(TriBlendMode::Shaded, thing->Alpha, 1.0 - thing->Alpha);
args.SetTexture(tex, thing->Translation, true);
}
else
{
args.uniforms.destalpha = (uint32_t)(256 - thing->Alpha * 256);
args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256);
blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add;
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, thing->Alpha, 1.0 - thing->Alpha);
}
if (blendmode == TriBlendMode::Shaded)
{
args.SetTexture(tex, thing->Translation, true);
}
if (!PolyRenderer::Instance()->RenderTarget->IsBgra())
{
uint32_t r = (args.uniforms.color >> 16) & 0xff;
uint32_t g = (args.uniforms.color >> 8) & 0xff;
uint32_t b = args.uniforms.color & 0xff;
args.uniforms.color = RGB32k.RGB[r >> 3][g >> 3][b >> 3];
if (blendmode == TriBlendMode::Sub) // Sub crashes in pal mode for some weird reason.
blendmode = TriBlendMode::Add;
}
args.subsectorTest = true;
args.writeSubsector = false;
args.writeStencil = false;
args.blendmode = blendmode;
PolyTriangleDrawer::draw(args);
args.SetSubsectorDepthTest(true);
args.SetWriteSubsectorDepth(false);
args.SetWriteStencil(false);
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
}
bool RenderPolySprite::IsThingCulled(AActor *thing)

View file

@ -24,12 +24,10 @@
#include "polyrenderer/drawers/poly_triangle.h"
class Vec4f;
class RenderPolySprite
{
public:
void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, float t1, float t2);
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, float t1, float t2);
static bool GetLine(AActor *thing, DVector2 &left, DVector2 &right);
static bool IsThingCulled(AActor *thing);

View file

@ -37,7 +37,7 @@
EXTERN_CVAR(Bool, r_drawmirrors)
bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject*> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals)
bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject*> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals)
{
PolyDrawLinePortal *polyportal = nullptr;
if (line->backsector == nullptr && line->linedef && line->sidedef == line->linedef->sidedef[0] && (line->linedef->special == Line_Mirror && r_drawmirrors))
@ -165,7 +165,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipP
return polyportal != nullptr;
}
void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject*> &translucentWallsOutput)
void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject*> &translucentWallsOutput)
{
double frontceilz1 = fakeFloor->top.plane->ZatPoint(line->v1);
double frontfloorz1 = fakeFloor->bottom.plane->ZatPoint(line->v1);
@ -198,7 +198,7 @@ void RenderPolyWall::SetCoords(const DVector2 &v1, const DVector2 &v2, double ce
this->floor2 = floor2;
}
void RenderPolyWall::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull)
void RenderPolyWall::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull)
{
bool foggy = false;
FTexture *tex = GetTexture();
@ -248,32 +248,23 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane
}
PolyDrawArgs args;
args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy);
args.uniforms.light = (uint32_t)(GetLightLevel() / 255.0f * 256.0f);
args.uniforms.flags = TriUniforms::nearest_filter;
args.uniforms.subsectorDepth = SubsectorDepth;
args.objectToClip = &worldToClip;
args.vinput = vertices;
args.vcount = 4;
args.mode = TriangleDrawMode::Fan;
args.ccw = true;
args.stenciltestvalue = StencilValue;
args.stencilwritevalue = StencilValue + 1;
args.SetLight(GetColorTable(Line->frontsector->Colormap, Line->frontsector->SpecialColors[sector_t::walltop]), GetLightLevel(), PolyRenderer::Instance()->Light.WallGlobVis(foggy), false);
args.SetSubsectorDepth(SubsectorDepth);
args.SetTransform(&worldToClip);
args.SetFaceCullCCW(true);
args.SetStencilTestValue(StencilValue);
args.SetWriteStencil(true, StencilValue + 1);
if (tex)
args.SetTexture(tex);
args.SetColormap(GetColorTable(Line->frontsector->Colormap, Line->frontsector->SpecialColors[sector_t::walltop]));
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
//if (Side && Side->lighthead)
// args.uniforms.light = 255; // Make walls touched by a light fullbright!
args.SetClipPlane(clipPlane);
if (Polyportal)
{
args.stencilwritevalue = Polyportal->StencilValue;
args.writeColor = false;
args.writeSubsector = false;
PolyTriangleDrawer::draw(args);
Polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, args.uniforms.subsectorDepth });
args.SetWriteStencil(true, Polyportal->StencilValue);
args.SetWriteColor(false);
args.SetWriteSubsectorDepth(false);
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
Polyportal->Shape.push_back({ vertices, 4, true, SubsectorDepth });
angle_t angle1, angle2;
if (cull.GetAnglesForLine(v1.X, v1.Y, v2.X, v2.Y, angle1, angle2))
@ -281,21 +272,16 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane
}
else if (!Masked)
{
args.blendmode = TriBlendMode::Copy;
PolyTriangleDrawer::draw(args);
args.SetStyle(TriBlendMode::Copy);
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
}
else
{
args.uniforms.destalpha = (Line->flags & ML_ADDTRANS) ? 256 : (uint32_t)(256 - Line->alpha * 256);
args.uniforms.srcalpha = (uint32_t)(Line->alpha * 256);
args.subsectorTest = true;
args.writeSubsector = false;
args.writeStencil = false;
if (args.uniforms.destalpha == 0 && args.uniforms.srcalpha == 256)
args.blendmode = TriBlendMode::AlphaBlend;
else
args.blendmode = TriBlendMode::Add;
PolyTriangleDrawer::draw(args);
args.SetStyle((Line->flags & ML_ADDTRANS) ? TriBlendMode::Add : TriBlendMode::AlphaBlend, Line->alpha, 1.0);
args.SetSubsectorDepthTest(true);
args.SetWriteSubsectorDepth(true);
args.SetWriteStencil(false);
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
}
RenderPolyDecal::RenderWallDecals(worldToClip, clipPlane, LineSeg, SubsectorDepth, StencilValue);

View file

@ -27,16 +27,15 @@
class PolyTranslucentObject;
class PolyDrawLinePortal;
class PolyCull;
class Vec4f;
class RenderPolyWall
{
public:
static bool RenderLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject*> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals);
static void Render3DFloorLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject*> &translucentWallsOutput);
static bool RenderLine(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject*> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals);
static void Render3DFloorLine(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject*> &translucentWallsOutput);
void SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2);
void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull);
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull);
DVector2 v1;
DVector2 v2;

View file

@ -29,7 +29,7 @@
#include "polyrenderer/poly_renderer.h"
#include "polyrenderer/scene/poly_light.h"
void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue)
void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue)
{
if (RenderPolySprite::IsThingCulled(thing))
return;
@ -97,35 +97,18 @@ void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const Vec4f &cli
}
bool fullbrightSprite = ((thing->renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT));
PolyCameraLight *cameraLight = PolyCameraLight::Instance();
int lightlevel = fullbrightSprite ? 255 : thing->Sector->lightlevel + actualextralight;
PolyDrawArgs args;
args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy);
if (fullbrightSprite || cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap())
{
args.uniforms.light = 256;
args.uniforms.flags = TriUniforms::fixed_light | TriUniforms::nearest_filter;
}
else
{
args.uniforms.light = (uint32_t)((thing->Sector->lightlevel + actualextralight) / 255.0f * 256.0f);
args.uniforms.flags = TriUniforms::nearest_filter;
}
args.uniforms.subsectorDepth = subsectorDepth;
args.objectToClip = &worldToClip;
args.vinput = vertices;
args.vcount = 4;
args.mode = TriangleDrawMode::Fan;
args.ccw = true;
args.stenciltestvalue = stencilValue;
args.stencilwritevalue = stencilValue;
args.SetLight(GetColorTable(sub->sector->Colormap, sub->sector->SpecialColors[sector_t::sprites], true), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), fullbrightSprite);
args.SetTransform(&worldToClip);
args.SetFaceCullCCW(true);
args.SetStencilTestValue(stencilValue);
args.SetTexture(tex);
args.SetColormap(GetColorTable(sub->sector->Colormap, sub->sector->SpecialColors[sector_t::sprites], true));
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
args.subsectorTest = true;
args.writeSubsector = false;
args.writeStencil = false;
args.blendmode = TriBlendMode::AlphaBlend;
PolyTriangleDrawer::draw(args);
args.SetClipPlane(clipPlane);
args.SetSubsectorDepthTest(true);
args.SetWriteSubsectorDepth(false);
args.SetWriteStencil(false);
args.SetStyle(TriBlendMode::AlphaBlend);
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
}

View file

@ -24,10 +24,8 @@
#include "polyrenderer/drawers/poly_triangle.h"
class Vec4f;
class RenderPolyWallSprite
{
public:
void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue);
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue);
};

View file

@ -84,6 +84,7 @@ int I_PickIWad_Gtk (WadStuff *wads, int numwads, bool showwin, int defaultiwad);
int I_PickIWad_Cocoa (WadStuff *wads, int numwads, bool showwin, int defaultiwad);
#endif
double PerfToSec, PerfToMillisec;
uint32_t LanguageIDs[4];
int (*I_GetTime) (bool saveMS);