diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0100d5c311..3a3efad308 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 diff --git a/src/polyrenderer/drawers/poly_draw_args.cpp b/src/polyrenderer/drawers/poly_draw_args.cpp index d8f93d3881..eaa812dc91 100644 --- a/src/polyrenderer/drawers/poly_draw_args.cpp +++ b/src/polyrenderer/drawers/poly_draw_args.cpp @@ -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(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(*this, PolyTriangleDrawer::is_mirror()); } diff --git a/src/polyrenderer/drawers/poly_draw_args.h b/src/polyrenderer/drawers/poly_draw_args.h index bf38ffab9e..20c73ec583 100644 --- a/src/polyrenderer/drawers/poly_draw_args.h +++ b/src/polyrenderer/drawers/poly_draw_args.h @@ -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; }; diff --git a/src/polyrenderer/drawers/poly_drawer32_sse2.h b/src/polyrenderer/drawers/poly_drawer32_sse2.h index c86d3bc934..a3568b6c1e 100644 --- a/src/polyrenderer/drawers/poly_drawer32_sse2.h +++ b/src/polyrenderer/drawers/poly_drawer32_sse2.h @@ -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 { diff --git a/src/polyrenderer/drawers/poly_drawer8.h b/src/polyrenderer/drawers/poly_drawer8.h index 6535f48529..2ae40e5247 100644 --- a/src/polyrenderer/drawers/poly_drawer8.h +++ b/src/polyrenderer/drawers/poly_drawer8.h @@ -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++) { diff --git a/src/polyrenderer/drawers/poly_triangle.cpp b/src/polyrenderer/drawers/poly_triangle.cpp index fa4b8b98c1..d07102f1ea 100644 --- a/src/polyrenderer/drawers/poly_triangle.cpp +++ b/src/polyrenderer/drawers/poly_triangle.cpp @@ -80,35 +80,35 @@ void PolyTriangleDrawer::toggle_mirror() mirror = !mirror; } -void PolyTriangleDrawer::draw(const PolyDrawArgs &args) +bool PolyTriangleDrawer::is_mirror() { - PolyRenderer::Instance()->DrawQueue->Push(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; -} diff --git a/src/polyrenderer/drawers/poly_triangle.h b/src/polyrenderer/drawers/poly_triangle.h index a52faa3266..d3019fc36a 100644 --- a/src/polyrenderer/drawers/poly_triangle.h +++ b/src/polyrenderer/drawers/poly_triangle.h @@ -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; diff --git a/src/polyrenderer/drawers/screen_triangle.cpp b/src/polyrenderer/drawers/screen_triangle.cpp index 37a14c0628..ab0928d0ee 100644 --- a/src/polyrenderer/drawers/screen_triangle.cpp +++ b/src/polyrenderer/drawers/screen_triangle.cpp @@ -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; diff --git a/src/polyrenderer/drawers/screen_triangle.h b/src/polyrenderer/drawers/screen_triangle.h index 470029c841..81d7cdb68e 100644 --- a/src/polyrenderer/drawers/screen_triangle.h +++ b/src/polyrenderer/drawers/screen_triangle.h @@ -26,6 +26,7 @@ #include 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 diff --git a/src/polyrenderer/math/poly_intersection.cpp b/src/polyrenderer/math/poly_intersection.cpp deleted file mode 100644 index ed5e8ef438..0000000000 --- a/src/polyrenderer/math/poly_intersection.cpp +++ /dev/null @@ -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 -#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 ¢er1, float radius1, const Vec3f ¢er2, 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 ¢er, 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; -} diff --git a/src/polyrenderer/math/poly_intersection.h b/src/polyrenderer/math/poly_intersection.h deleted file mode 100644 index 438146fce3..0000000000 --- a/src/polyrenderer/math/poly_intersection.h +++ /dev/null @@ -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 -#include - -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 - 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 ¢er1, float radius1, const Vec3f ¢er2, float radius2); - static OverlapResult sphere_aabb(const Vec3f ¢er, 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); -}; diff --git a/src/polyrenderer/poly_all.cpp b/src/polyrenderer/poly_all.cpp index 2ad4b45a45..286dae4cb9 100644 --- a/src/polyrenderer/poly_all.cpp +++ b/src/polyrenderer/poly_all.cpp @@ -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" diff --git a/src/polyrenderer/poly_renderer.cpp b/src/polyrenderer/poly_renderer.cpp index a8e6f34c21..9cf2824548 100644 --- a/src/polyrenderer/poly_renderer.cpp +++ b/src/polyrenderer/poly_renderer.cpp @@ -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); diff --git a/src/polyrenderer/scene/poly_cull.cpp b/src/polyrenderer/scene/poly_cull.cpp index 01f157a93f..623b6e9df9 100644 --- a/src/polyrenderer/scene/poly_cull.cpp +++ b/src/polyrenderer/scene/poly_cull.cpp @@ -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] = { diff --git a/src/polyrenderer/scene/poly_cull.h b/src/polyrenderer/scene/poly_cull.h index d0430501d9..64e4d57399 100644 --- a/src/polyrenderer/scene/poly_cull.h +++ b/src/polyrenderer/scene/poly_cull.h @@ -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); diff --git a/src/polyrenderer/scene/poly_decal.cpp b/src/polyrenderer/scene/poly_decal.cpp index 0759ac64d4..829f444b6d 100644 --- a/src/polyrenderer/scene/poly_decal.cpp +++ b/src/polyrenderer/scene/poly_decal.cpp @@ -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); } diff --git a/src/polyrenderer/scene/poly_decal.h b/src/polyrenderer/scene/poly_decal.h index 48907780a8..a0d676951c 100644 --- a/src/polyrenderer/scene/poly_decal.h +++ b/src/polyrenderer/scene/poly_decal.h @@ -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); }; diff --git a/src/polyrenderer/scene/poly_light.cpp b/src/polyrenderer/scene/poly_light.cpp index 5de6756d7e..92c74e4695 100644 --- a/src/polyrenderer/scene/poly_light.cpp +++ b/src/polyrenderer/scene/poly_light.cpp @@ -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; +} diff --git a/src/polyrenderer/scene/poly_light.h b/src/polyrenderer/scene/poly_light.h index 9644387e71..dcb397cb82 100644 --- a/src/polyrenderer/scene/poly_light.h +++ b/src/polyrenderer/scene/poly_light.h @@ -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; diff --git a/src/polyrenderer/scene/poly_particle.cpp b/src/polyrenderer/scene/poly_particle.cpp index 8d09be467f..d4a49334b9 100644 --- a/src/polyrenderer/scene/poly_particle.cpp +++ b/src/polyrenderer/scene/poly_particle.cpp @@ -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); } diff --git a/src/polyrenderer/scene/poly_particle.h b/src/polyrenderer/scene/poly_particle.h index b3b25b996d..e91174591c 100644 --- a/src/polyrenderer/scene/poly_particle.h +++ b/src/polyrenderer/scene/poly_particle.h @@ -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); }; diff --git a/src/polyrenderer/scene/poly_plane.cpp b/src/polyrenderer/scene/poly_plane.cpp index 03ea75b37a..d41328d573 100644 --- a/src/polyrenderer/scene/poly_plane.cpp +++ b/src/polyrenderer/scene/poly_plane.cpp @@ -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> §orPortals) +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> §orPortals) { 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(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> §orPortals) +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> §orPortals) { 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(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 }); } } } diff --git a/src/polyrenderer/scene/poly_plane.h b/src/polyrenderer/scene/poly_plane.h index bf844dcc27..ce21925945 100644 --- a/src/polyrenderer/scene/poly_plane.h +++ b/src/polyrenderer/scene/poly_plane.h @@ -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> §orPortals); + 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> §orPortals); 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> §orPortals); + 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> §orPortals); TriVertex PlaneVertex(vertex_t *v1, double height, const UVTransform &transform); }; diff --git a/src/polyrenderer/scene/poly_portal.cpp b/src/polyrenderer/scene/poly_portal.cpp index f262134552..0e0ffbf38a 100644 --- a/src/polyrenderer/scene/poly_portal.cpp +++ b/src/polyrenderer/scene/poly_portal.cpp @@ -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); diff --git a/src/polyrenderer/scene/poly_scene.cpp b/src/polyrenderer/scene/poly_scene.cpp index f3a0b28879..3aeda994ce 100644 --- a/src/polyrenderer/scene/poly_scene.cpp +++ b/src/polyrenderer/scene/poly_scene.cpp @@ -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); } } } diff --git a/src/polyrenderer/scene/poly_scene.h b/src/polyrenderer/scene/poly_scene.h index 77c7925c0a..707ee87a3c 100644 --- a/src/polyrenderer/scene/poly_scene.h +++ b/src/polyrenderer/scene/poly_scene.h @@ -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 &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; diff --git a/src/polyrenderer/scene/poly_sky.cpp b/src/polyrenderer/scene/poly_sky.cpp index 3be38e4813..374163f967 100644 --- a/src/polyrenderer/scene/poly_sky.cpp +++ b/src/polyrenderer/scene/poly_sky.cpp @@ -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() diff --git a/src/polyrenderer/scene/poly_sprite.cpp b/src/polyrenderer/scene/poly_sprite.cpp index 6e3c8c86c2..2a98af7212 100644 --- a/src/polyrenderer/scene/poly_sprite.cpp +++ b/src/polyrenderer/scene/poly_sprite.cpp @@ -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) diff --git a/src/polyrenderer/scene/poly_sprite.h b/src/polyrenderer/scene/poly_sprite.h index a61c7f4b5f..e190d9ee6c 100644 --- a/src/polyrenderer/scene/poly_sprite.h +++ b/src/polyrenderer/scene/poly_sprite.h @@ -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); diff --git a/src/polyrenderer/scene/poly_wall.cpp b/src/polyrenderer/scene/poly_wall.cpp index abbfd15f88..263487f709 100644 --- a/src/polyrenderer/scene/poly_wall.cpp +++ b/src/polyrenderer/scene/poly_wall.cpp @@ -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 &translucentWallsOutput, std::vector> &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 &translucentWallsOutput, std::vector> &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 &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 &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); diff --git a/src/polyrenderer/scene/poly_wall.h b/src/polyrenderer/scene/poly_wall.h index a435201b29..dda2cdc2aa 100644 --- a/src/polyrenderer/scene/poly_wall.h +++ b/src/polyrenderer/scene/poly_wall.h @@ -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 &translucentWallsOutput, std::vector> &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 &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 &translucentWallsOutput, std::vector> &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 &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; diff --git a/src/polyrenderer/scene/poly_wallsprite.cpp b/src/polyrenderer/scene/poly_wallsprite.cpp index 75227c2557..8108849b9e 100644 --- a/src/polyrenderer/scene/poly_wallsprite.cpp +++ b/src/polyrenderer/scene/poly_wallsprite.cpp @@ -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); } diff --git a/src/polyrenderer/scene/poly_wallsprite.h b/src/polyrenderer/scene/poly_wallsprite.h index 75a550748e..c0c0005b86 100644 --- a/src/polyrenderer/scene/poly_wallsprite.h +++ b/src/polyrenderer/scene/poly_wallsprite.h @@ -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); }; diff --git a/src/posix/sdl/i_system.cpp b/src/posix/sdl/i_system.cpp index e00f137a7a..01457c012f 100644 --- a/src/posix/sdl/i_system.cpp +++ b/src/posix/sdl/i_system.cpp @@ -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);