diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 16c23743a..59dd637a2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -416,11 +416,6 @@ if( NOT MSVC ) add_definitions( -D__forceinline=inline ) endif() -# Fix stat in v140_xp (broken in RTM and Update 1 so far) -if( MSVC AND MSVC_VERSION EQUAL 1900 AND CMAKE_GENERATOR_TOOLSET STREQUAL "v140_xp" ) - add_definitions( -D_stat64i32=VS14Stat ) -endif() - if( UNIX ) CHECK_LIBRARY_EXISTS( rt clock_gettime "" CLOCK_GETTIME_IN_RT ) if( NOT CLOCK_GETTIME_IN_RT ) diff --git a/src/c_cvars.cpp b/src/c_cvars.cpp index 2e8e22ecc..605338b01 100644 --- a/src/c_cvars.cpp +++ b/src/c_cvars.cpp @@ -67,6 +67,19 @@ int cvar_defflags; FBaseCVar::FBaseCVar (const char *var_name, uint32_t flags, void (*callback)(FBaseCVar &)) { + if (var_name != nullptr && (flags & CVAR_SERVERINFO)) + { + // This limitation is imposed by network protocol which uses only 6 bits + // for name's length with terminating null character + static const size_t NAME_LENGHT_MAX = 63; + + if (strlen(var_name) > NAME_LENGHT_MAX) + { + I_FatalError("Name of the server console variable \"%s\" is too long.\n" + "Its length should not exceed %zu characters.\n", var_name, NAME_LENGHT_MAX); + } + } + FBaseCVar *var; var = FindCVar (var_name, NULL); diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 25b2ff236..3f8ede410 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -606,10 +606,7 @@ void GLSkyboxPortal::DrawContents(FDrawInfo *di) di->SetViewArea(); ClearClipper(di); - int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection; - - di->CurrentMapSections.Zero(); - di->CurrentMapSections.Set(mapsection); + di->UpdateCurrentMapSection(); drawer->DrawScene(di, DM_SKYPORTAL); portal->mFlags &= ~PORTSF_INSKYBOX; @@ -770,6 +767,8 @@ void GLPlaneMirrorPortal::DrawContents(FDrawInfo *di) drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1)); ClearClipper(di); + di->UpdateCurrentMapSection(); + gl_RenderState.SetClipHeight(planez, PlaneMirrorMode < 0 ? -1.f : 1.f); drawer->DrawScene(di, DM_PORTAL); gl_RenderState.SetClipHeight(0.f, 0.f); @@ -875,6 +874,8 @@ void GLMirrorPortal::DrawContents(FDrawInfo *di) return; } + di->UpdateCurrentMapSection(); + di->mClipPortal = this; DAngle StartAngle = r_viewpoint.Angles.Yaw; DVector3 StartPos = r_viewpoint.Pos; diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index f2e0301fb..91d4e4235 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -739,6 +739,8 @@ void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width, GLRenderer->CopyToBackbuffer(&bounds, false); glFlush(); + screen->SetOutputViewport(nullptr); + uint8_t * scr = (uint8_t *)M_Malloc(width * height * 3); glReadPixels(0,0,width, height,GL_RGB,GL_UNSIGNED_BYTE,scr); M_CreatePNG (file, scr + ((height-1) * width * 3), NULL, SS_RGB, width, height, -width * 3, Gamma); diff --git a/src/gl/scene/gl_scenedrawer.h b/src/gl/scene/gl_scenedrawer.h index d075e1418..3396c269c 100644 --- a/src/gl/scene/gl_scenedrawer.h +++ b/src/gl/scene/gl_scenedrawer.h @@ -32,7 +32,6 @@ public: angle_t FrustumAngle(); void SetViewMatrix(float vx, float vy, float vz, bool mirror, bool planemirror); - void SetViewArea(); void SetupView(float vx, float vy, float vz, DAngle va, bool mirror, bool planemirror); void SetViewAngle(DAngle viewangle); void SetProjection(VSMatrix matrix); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 2dbe156dd..1180e557c 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -351,6 +351,9 @@ void FDrawInfo::AddMirrorSurface(GLWall *w) auto newwall = drawlists[GLDL_TRANSLUCENTBORDER].NewWall(); *newwall = *w; + // Invalidate vertices to allow setting of texture coordinates + newwall->vertcount = 0; + FVector3 v = newwall->glseg.Normal(); auto tcs = newwall->tcs; tcs[GLWall::LOLFT].u = tcs[GLWall::LORGT].u = tcs[GLWall::UPLFT].u = tcs[GLWall::UPRGT].u = v.X; diff --git a/src/hwrenderer/scene/hw_drawinfo.h b/src/hwrenderer/scene/hw_drawinfo.h index e9db60a09..8bec0df27 100644 --- a/src/hwrenderer/scene/hw_drawinfo.h +++ b/src/hwrenderer/scene/hw_drawinfo.h @@ -175,6 +175,8 @@ public: void PreparePlayerSprites(sector_t * viewsector, area_t in_area); void PrepareTargeterSprites(); + void UpdateCurrentMapSection(); + virtual void DrawWall(GLWall *wall, int pass) = 0; virtual void DrawFlat(GLFlat *flat, int pass, bool trans) = 0; virtual void DrawSprite(GLSprite *sprite, int pass) = 0; diff --git a/src/hwrenderer/scene/hw_drawstructs.h b/src/hwrenderer/scene/hw_drawstructs.h index 5758cf0b8..8dcc4632a 100644 --- a/src/hwrenderer/scene/hw_drawstructs.h +++ b/src/hwrenderer/scene/hw_drawstructs.h @@ -250,12 +250,15 @@ public: void ProcessDecal(HWDrawInfo *di, DBaseDecal *decal, const FVector3 &normal); void ProcessDecals(HWDrawInfo *di); - void CreateVertices(FFlatVertex *&ptr, bool nosplit); + int CreateVertices(FFlatVertex *&ptr, bool nosplit); void SplitLeftEdge (FFlatVertex *&ptr); void SplitRightEdge(FFlatVertex *&ptr); void SplitUpperEdge(FFlatVertex *&ptr); void SplitLowerEdge(FFlatVertex *&ptr); + void CountLeftEdge (unsigned &ptr); + void CountRightEdge(unsigned &ptr); + int CountVertices(); public: diff --git a/src/hwrenderer/scene/hw_renderhacks.cpp b/src/hwrenderer/scene/hw_renderhacks.cpp index 57fef57e0..74c5b3f0e 100644 --- a/src/hwrenderer/scene/hw_renderhacks.cpp +++ b/src/hwrenderer/scene/hw_renderhacks.cpp @@ -86,6 +86,12 @@ void HWDrawInfo::ClearBuffers() mClipPortal = nullptr; } +void HWDrawInfo::UpdateCurrentMapSection() +{ + const int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection; + CurrentMapSections.Set(mapsection); +} + //========================================================================== // // Adds a subsector plane to a sector's render list diff --git a/src/hwrenderer/scene/hw_walls.cpp b/src/hwrenderer/scene/hw_walls.cpp index 1ed41122a..b70c4ebf8 100644 --- a/src/hwrenderer/scene/hw_walls.cpp +++ b/src/hwrenderer/scene/hw_walls.cpp @@ -1522,6 +1522,7 @@ void GLWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_ } v1 = seg->v1; v2 = seg->v2; + flags |= GLWF_NOSPLITLOWER | GLWF_NOSPLITLOWER; // seg-splitting not needed for single segs. } diff --git a/src/hwrenderer/scene/hw_walls_vertex.cpp b/src/hwrenderer/scene/hw_walls_vertex.cpp index 6d74a2369..b0042baff 100644 --- a/src/hwrenderer/scene/hw_walls_vertex.cpp +++ b/src/hwrenderer/scene/hw_walls_vertex.cpp @@ -170,8 +170,9 @@ void GLWall::SplitRightEdge(FFlatVertex *&ptr) // //========================================================================== -void GLWall::CreateVertices(FFlatVertex *&ptr, bool split) +int GLWall::CreateVertices(FFlatVertex *&ptr, bool split) { + auto oo = ptr; ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v); ptr++; if (split && glseg.fracleft == 0) SplitLeftEdge(ptr); @@ -184,6 +185,58 @@ void GLWall::CreateVertices(FFlatVertex *&ptr, bool split) ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[LORGT].u, tcs[LORGT].v); ptr++; if (split && !(flags & GLWF_NOSPLITLOWER) && seg->sidedef->numsegs > 1) SplitLowerEdge(ptr); + return int(ptr - oo); +} + + +//========================================================================== +// +// Split left edge of wall +// +//========================================================================== + +void GLWall::CountLeftEdge(unsigned &ptr) +{ + if (vertexes[0] == NULL) return; + + vertex_t * vi = vertexes[0]; + + if (vi->numheights) + { + int i = 0; + + while (inumheights && vi->heightlist[i] <= zbottom[0]) i++; + while (inumheights && vi->heightlist[i] < ztop[0]) + { + ptr++; + i++; + } + } +} + +//========================================================================== +// +// Split right edge of wall +// +//========================================================================== + +void GLWall::CountRightEdge(unsigned &ptr) +{ + if (vertexes[1] == NULL) return; + + vertex_t * vi = vertexes[1]; + + if (vi->numheights) + { + int i = vi->numheights - 1; + + while (i>0 && vi->heightlist[i] >= ztop[1]) i--; + while (i>0 && vi->heightlist[i] > zbottom[1]) + { + ptr++; + i--; + } + } } //========================================================================== @@ -194,49 +247,13 @@ void GLWall::CreateVertices(FFlatVertex *&ptr, bool split) int GLWall::CountVertices() { - int cnt = 4; - vertex_t * vi = vertexes[0]; - if (glseg.fracleft == 0 && vi != nullptr && vi->numheights) - { - int i = 0; - - while (inumheights && vi->heightlist[i] <= zbottom[0]) i++; - while (inumheights && vi->heightlist[i] < ztop[0]) - { - i++; - cnt++; - } - } - auto sidedef = seg->sidedef; - constexpr auto NOSPLIT_LOWER_UPPER = GLWF_NOSPLITLOWER | GLWF_NOSPLITUPPER; - const bool canSplit = (flags & NOSPLIT_LOWER_UPPER) != NOSPLIT_LOWER_UPPER; - if (canSplit && sidedef->numsegs > 1) - { - int cnt2 = 0; - for (int i = sidedef->numsegs - 2; i >= 0; i--) - { - float sidefrac = sidedef->segs[i]->sidefrac; - if (sidefrac >= glseg.fracright) continue; - if (sidefrac <= glseg.fracleft) break; - cnt2++; - } - const bool splitBoth = !(flags & NOSPLIT_LOWER_UPPER); - if (splitBoth) cnt2 <<= 1; - cnt += cnt2; - } - vi = vertexes[1]; - if (glseg.fracright == 1 && vi != nullptr && vi->numheights) - { - int i = 0; - - while (inumheights && vi->heightlist[i] <= zbottom[1]) i++; - while (inumheights && vi->heightlist[i] < ztop[1]) - { - i++; - cnt++; - } - } - return cnt; + unsigned ptr = 4; + if (glseg.fracleft == 0) CountLeftEdge(ptr); + if (glseg.fracright == 1) CountRightEdge(ptr); + // This may allocate a few vertices too many in case of a split linedef but this is a rare case that isn't worth the required overhead for a precise calculation. + if (!(flags & GLWF_NOSPLITUPPER)) ptr += seg->sidedef->numsegs - 1; + if (!(flags & GLWF_NOSPLITLOWER)) ptr += seg->sidedef->numsegs - 1; + return (int)ptr; } //========================================================================== @@ -250,11 +267,9 @@ void GLWall::MakeVertices(HWDrawInfo *di, bool nosplit) if (vertcount == 0) { bool split = (gl_seamless && !nosplit && seg->sidedef != nullptr && !(seg->sidedef->Flags & WALLF_POLYOBJ) && !(flags & GLWF_NOSPLIT)); - vertcount = split ? CountVertices() : 4; - - auto ret = di->AllocVertices(vertcount); + auto ret = di->AllocVertices(split ? CountVertices() : 4); vertindex = ret.second; - CreateVertices(ret.first, split); + vertcount = CreateVertices(ret.first, split); } } diff --git a/src/polyrenderer/drawers/poly_draw_args.cpp b/src/polyrenderer/drawers/poly_draw_args.cpp index 532bd93d9..8aa79f70b 100644 --- a/src/polyrenderer/drawers/poly_draw_args.cpp +++ b/src/polyrenderer/drawers/poly_draw_args.cpp @@ -52,7 +52,7 @@ void PolyDrawArgs::SetTexture(FTexture *texture, FRenderStyle style) mTexture = texture; mTextureWidth = texture->GetWidth(); mTextureHeight = texture->GetHeight(); - if (PolyRenderer::Instance()->RenderTarget->IsBgra()) + if (PolyTriangleDrawer::IsBgra()) mTexturePixels = (const uint8_t *)texture->GetPixelsBgra(); else mTexturePixels = texture->GetPixels(style); @@ -67,7 +67,7 @@ void PolyDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, FRender FRemapTable *table = TranslationToTable(translationID); if (table != nullptr && !table->Inactive) { - if (PolyRenderer::Instance()->RenderTarget->IsBgra()) + if (PolyTriangleDrawer::IsBgra()) mTranslation = (uint8_t*)table->Palette; else mTranslation = table->Remap; @@ -121,7 +121,7 @@ void PolyDrawArgs::SetLight(FSWColormap *base_colormap, uint32_t lightlevel, dou void PolyDrawArgs::SetColor(uint32_t bgra, uint8_t palindex) { - if (PolyRenderer::Instance()->RenderTarget->IsBgra()) + if (PolyTriangleDrawer::IsBgra()) { mColor = bgra; } @@ -152,59 +152,61 @@ void PolyDrawArgs::DrawElements(const DrawerCommandQueuePtr &queue, const TriVer void PolyDrawArgs::SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *tex, bool fullbright) { SetTexture(tex, translationID, renderstyle); - + SetColor(0xff000000 | fillcolor, fillcolor >> 24); + if (renderstyle == LegacyRenderStyles[STYLE_Normal] || (r_drawfuzz == 0 && renderstyle == LegacyRenderStyles[STYLE_OptFuzzy])) { - SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, 1.0, 0.0); + SetStyle(Translation() ? TriBlendMode::NormalTranslated : TriBlendMode::Normal, alpha); } else if (renderstyle == LegacyRenderStyles[STYLE_Add] && fullbright && alpha == 1.0 && !Translation()) { - SetStyle(TriBlendMode::TextureAddSrcColor, 1.0, 1.0); - } - else if (renderstyle == LegacyRenderStyles[STYLE_Add]) - { - SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, alpha, 1.0); - } - else if (renderstyle == LegacyRenderStyles[STYLE_Subtract]) - { - SetStyle(Translation() ? TriBlendMode::TranslatedRevSub : TriBlendMode::TextureRevSub, alpha, 1.0); + SetStyle(TriBlendMode::SrcColor, alpha); } else if (renderstyle == LegacyRenderStyles[STYLE_SoulTrans]) { - SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, transsouls, 1.0 - transsouls); + SetStyle(Translation() ? TriBlendMode::AddTranslated : TriBlendMode::Add, transsouls); } else if (renderstyle == LegacyRenderStyles[STYLE_Fuzzy] || (r_drawfuzz == 1 && renderstyle == LegacyRenderStyles[STYLE_OptFuzzy])) { SetColor(0xff000000, 0); - SetStyle(TriBlendMode::Fuzz); + SetStyle(TriBlendMode::Fuzzy); } else if (renderstyle == LegacyRenderStyles[STYLE_Shadow] || (r_drawfuzz == 2 && renderstyle == LegacyRenderStyles[STYLE_OptFuzzy])) { - SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, 0.0, 160 / 255.0); + SetColor(0xff000000, 0); + SetStyle(Translation() ? TriBlendMode::TranslucentStencilTranslated : TriBlendMode::TranslucentStencil, 1.0 - 160 / 255.0); } - else if (renderstyle == LegacyRenderStyles[STYLE_TranslucentStencil]) + else if (renderstyle == LegacyRenderStyles[STYLE_Stencil]) { - SetColor(0xff000000 | fillcolor, fillcolor >> 24); - SetStyle(TriBlendMode::Stencil, alpha, 1.0 - alpha); + SetStyle(Translation() ? TriBlendMode::StencilTranslated : TriBlendMode::Stencil, alpha); } - else if (renderstyle == LegacyRenderStyles[STYLE_AddStencil]) + else if (renderstyle == LegacyRenderStyles[STYLE_Translucent]) { - SetColor(0xff000000 | fillcolor, fillcolor >> 24); - SetStyle(TriBlendMode::AddStencil, alpha, 1.0); + SetStyle(Translation() ? TriBlendMode::TranslucentTranslated : TriBlendMode::Translucent, alpha); + } + else if (renderstyle == LegacyRenderStyles[STYLE_Add]) + { + SetStyle(Translation() ? TriBlendMode::AddTranslated : TriBlendMode::Add, alpha); } else if (renderstyle == LegacyRenderStyles[STYLE_Shaded]) { - SetColor(0xff000000 | fillcolor, fillcolor >> 24); - SetStyle(TriBlendMode::Shaded, alpha, 1.0 - alpha); + SetStyle(Translation() ? TriBlendMode::ShadedTranslated : TriBlendMode::Shaded, alpha); + } + else if (renderstyle == LegacyRenderStyles[STYLE_TranslucentStencil]) + { + SetStyle(Translation() ? TriBlendMode::TranslucentStencilTranslated : TriBlendMode::TranslucentStencil, alpha); + } + else if (renderstyle == LegacyRenderStyles[STYLE_Subtract]) + { + SetStyle(Translation() ? TriBlendMode::SubtractTranslated : TriBlendMode::Subtract, alpha); + } + else if (renderstyle == LegacyRenderStyles[STYLE_AddStencil]) + { + SetStyle(Translation() ? TriBlendMode::AddStencilTranslated : TriBlendMode::AddStencil, alpha); } else if (renderstyle == LegacyRenderStyles[STYLE_AddShaded]) { - SetColor(0xff000000 | fillcolor, fillcolor >> 24); - SetStyle(TriBlendMode::AddShaded, alpha, 1.0); - } - else - { - SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, alpha, 1.0 - alpha); + SetStyle(Translation() ? TriBlendMode::AddShadedTranslated : TriBlendMode::AddShaded, alpha); } } @@ -215,7 +217,7 @@ void RectDrawArgs::SetTexture(FTexture *texture, FRenderStyle style) mTexture = texture; mTextureWidth = texture->GetWidth(); mTextureHeight = texture->GetHeight(); - if (PolyRenderer::Instance()->RenderTarget->IsBgra()) + if (PolyTriangleDrawer::IsBgra()) mTexturePixels = (const uint8_t *)texture->GetPixelsBgra(); else mTexturePixels = texture->GetPixels(style); @@ -229,7 +231,7 @@ void RectDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, FRender FRemapTable *table = TranslationToTable(translationID); if (table != nullptr && !table->Inactive) { - if (PolyRenderer::Instance()->RenderTarget->IsBgra()) + if (PolyTriangleDrawer::IsBgra()) mTranslation = (uint8_t*)table->Palette; else mTranslation = table->Remap; @@ -273,7 +275,7 @@ void RectDrawArgs::SetLight(FSWColormap *base_colormap, uint32_t lightlevel) void RectDrawArgs::SetColor(uint32_t bgra, uint8_t palindex) { - if (PolyRenderer::Instance()->RenderTarget->IsBgra()) + if (PolyTriangleDrawer::IsBgra()) { mColor = bgra; } @@ -303,55 +305,55 @@ void RectDrawArgs::SetStyle(FRenderStyle renderstyle, double alpha, uint32_t fil if (renderstyle == LegacyRenderStyles[STYLE_Normal] || (r_drawfuzz == 0 && renderstyle == LegacyRenderStyles[STYLE_OptFuzzy])) { - SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, 1.0, 0.0); + SetStyle(Translation() ? RectBlendMode::TranslatedAdd : RectBlendMode::TextureAdd, 1.0, 0.0); } else if (renderstyle == LegacyRenderStyles[STYLE_Add] && fullbright && alpha == 1.0 && !Translation()) { - SetStyle(TriBlendMode::TextureAddSrcColor, 1.0, 1.0); + SetStyle(RectBlendMode::TextureAddSrcColor, 1.0, 1.0); } else if (renderstyle == LegacyRenderStyles[STYLE_Add]) { - SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, alpha, 1.0); + SetStyle(Translation() ? RectBlendMode::TranslatedAdd : RectBlendMode::TextureAdd, alpha, 1.0); } else if (renderstyle == LegacyRenderStyles[STYLE_Subtract]) { - SetStyle(Translation() ? TriBlendMode::TranslatedRevSub : TriBlendMode::TextureRevSub, alpha, 1.0); + SetStyle(Translation() ? RectBlendMode::TranslatedRevSub : RectBlendMode::TextureRevSub, alpha, 1.0); } else if (renderstyle == LegacyRenderStyles[STYLE_SoulTrans]) { - SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, transsouls, 1.0 - transsouls); + SetStyle(Translation() ? RectBlendMode::TranslatedAdd : RectBlendMode::TextureAdd, transsouls, 1.0 - transsouls); } else if (renderstyle == LegacyRenderStyles[STYLE_Fuzzy] || (r_drawfuzz == 1 && renderstyle == LegacyRenderStyles[STYLE_OptFuzzy])) { SetColor(0xff000000, 0); - SetStyle(TriBlendMode::Fuzz); + SetStyle(RectBlendMode::Fuzz); } else if (renderstyle == LegacyRenderStyles[STYLE_Shadow] || (r_drawfuzz == 2 && renderstyle == LegacyRenderStyles[STYLE_OptFuzzy])) { - SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, 0.0, 160 / 255.0); + SetStyle(Translation() ? RectBlendMode::TranslatedAdd : RectBlendMode::TextureAdd, 0.0, 160 / 255.0); } else if (renderstyle == LegacyRenderStyles[STYLE_TranslucentStencil]) { SetColor(0xff000000 | fillcolor, fillcolor >> 24); - SetStyle(TriBlendMode::Stencil, alpha, 1.0 - alpha); + SetStyle(RectBlendMode::Stencil, alpha, 1.0 - alpha); } else if (renderstyle == LegacyRenderStyles[STYLE_AddStencil]) { SetColor(0xff000000 | fillcolor, fillcolor >> 24); - SetStyle(TriBlendMode::AddStencil, alpha, 1.0); + SetStyle(RectBlendMode::AddStencil, alpha, 1.0); } else if (renderstyle == LegacyRenderStyles[STYLE_Shaded]) { SetColor(0xff000000 | fillcolor, fillcolor >> 24); - SetStyle(TriBlendMode::Shaded, alpha, 1.0 - alpha); + SetStyle(RectBlendMode::Shaded, alpha, 1.0 - alpha); } else if (renderstyle == LegacyRenderStyles[STYLE_AddShaded]) { SetColor(0xff000000 | fillcolor, fillcolor >> 24); - SetStyle(TriBlendMode::AddShaded, alpha, 1.0); + SetStyle(RectBlendMode::AddShaded, alpha, 1.0); } else { - SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, alpha, 1.0 - alpha); + SetStyle(Translation() ? RectBlendMode::TranslatedAdd : RectBlendMode::TextureAdd, alpha, 1.0 - alpha); } } diff --git a/src/polyrenderer/drawers/poly_draw_args.h b/src/polyrenderer/drawers/poly_draw_args.h index 0c10be6b8..88f174525 100644 --- a/src/polyrenderer/drawers/poly_draw_args.h +++ b/src/polyrenderer/drawers/poly_draw_args.h @@ -75,7 +75,7 @@ public: void SetWriteColor(bool enable) { mWriteColor = enable; } void SetWriteStencil(bool enable, uint8_t stencilWriteValue = 0) { mWriteStencil = enable; mStencilWriteValue = stencilWriteValue; } void SetWriteDepth(bool enable) { mWriteDepth = enable; } - void SetStyle(TriBlendMode blendmode, double srcalpha = 1.0, double destalpha = 1.0) { mBlendMode = blendmode; mSrcAlpha = (uint32_t)(srcalpha * 256.0 + 0.5); mDestAlpha = (uint32_t)(destalpha * 256.0 + 0.5); } + void SetStyle(TriBlendMode blendmode, double alpha = 1.0) { mBlendMode = blendmode; mAlpha = (uint32_t)(alpha * 256.0 + 0.5); } void SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *texture, bool fullbright); void SetColor(uint32_t bgra, uint8_t palindex); void SetLights(PolyLight *lights, int numLights) { mLights = lights; mNumLights = numLights; } @@ -107,8 +107,7 @@ public: TriBlendMode BlendMode() const { return mBlendMode; } uint32_t Color() const { return mColor; } - uint32_t SrcAlpha() const { return mSrcAlpha; } - uint32_t DestAlpha() const { return mDestAlpha; } + uint32_t Alpha() const { return mAlpha; } float GlobVis() const { return mGlobVis; } uint32_t Light() const { return mLight; } @@ -152,11 +151,10 @@ private: uint8_t mStencilWriteValue = 0; const uint8_t *mColormaps = nullptr; PolyClipPlane mClipPlane[3]; - TriBlendMode mBlendMode = TriBlendMode::FillOpaque; + TriBlendMode mBlendMode = TriBlendMode::Fill; uint32_t mLight = 0; uint32_t mColor = 0; - uint32_t mSrcAlpha = 0; - uint32_t mDestAlpha = 0; + uint32_t mAlpha = 0; uint16_t mLightAlpha = 0; uint16_t mLightRed = 0; uint16_t mLightGreen = 0; @@ -182,7 +180,7 @@ public: void SetTexture(FTexture *texture, FRenderStyle style); void SetTexture(FTexture *texture, uint32_t translationID, FRenderStyle style); void SetLight(FSWColormap *basecolormap, uint32_t lightlevel); - void SetStyle(TriBlendMode blendmode, double srcalpha = 1.0, double destalpha = 1.0) { mBlendMode = blendmode; mSrcAlpha = (uint32_t)(srcalpha * 256.0 + 0.5); mDestAlpha = (uint32_t)(destalpha * 256.0 + 0.5); } + void SetStyle(RectBlendMode blendmode, double srcalpha = 1.0, double destalpha = 1.0) { mBlendMode = blendmode; mSrcAlpha = (uint32_t)(srcalpha * 256.0 + 0.5); mDestAlpha = (uint32_t)(destalpha * 256.0 + 0.5); } void SetStyle(FRenderStyle renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *texture, bool fullbright); void SetColor(uint32_t bgra, uint8_t palindex); void Draw(PolyRenderThread *thread, double x0, double x1, double y0, double y1, double u0, double u1, double v0, double v1); @@ -193,7 +191,7 @@ public: int TextureHeight() const { return mTextureHeight; } const uint8_t *Translation() const { return mTranslation; } - TriBlendMode BlendMode() const { return mBlendMode; } + RectBlendMode BlendMode() const { return mBlendMode; } uint32_t Color() const { return mColor; } uint32_t SrcAlpha() const { return mSrcAlpha; } uint32_t DestAlpha() const { return mDestAlpha; } @@ -227,7 +225,7 @@ private: int mTextureHeight = 0; const uint8_t *mTranslation = nullptr; const uint8_t *mColormaps = nullptr; - TriBlendMode mBlendMode = TriBlendMode::FillOpaque; + RectBlendMode mBlendMode = RectBlendMode::FillOpaque; uint32_t mLight = 0; uint32_t mColor = 0; uint32_t mSrcAlpha = 0; diff --git a/src/polyrenderer/drawers/poly_drawer32.h b/src/polyrenderer/drawers/poly_drawer32.h index 0ec21ff91..4dae396de 100644 --- a/src/polyrenderer/drawers/poly_drawer32.h +++ b/src/polyrenderer/drawers/poly_drawer32.h @@ -328,453 +328,6 @@ namespace TriScreenDrawerModes } } -template -class TriScreenDrawer32 -{ -public: - static void Execute(int x, int y, uint32_t mask0, uint32_t mask1, const TriDrawTriangleArgs *args) - { - using namespace TriScreenDrawerModes; - - bool is_simple_shade = args->uniforms->SimpleShade(); - - if (SamplerT::Mode == (int)Samplers::Texture) - { - bool is_nearest_filter = args->uniforms->NearestFilter(); - - if (is_simple_shade) - { - if (is_nearest_filter) - DrawBlock(x, y, mask0, mask1, args); - else - DrawBlock(x, y, mask0, mask1, args); - } - else - { - if (is_nearest_filter) - DrawBlock(x, y, mask0, mask1, args); - else - DrawBlock(x, y, mask0, mask1, args); - } - } - else if (SamplerT::Mode == (int)Samplers::Fuzz) - { - DrawBlock(x, y, mask0, mask1, args); - } - else // no linear filtering for translated, shaded, stencil, fill or skycap - { - if (is_simple_shade) - { - DrawBlock(x, y, mask0, mask1, args); - } - else - { - DrawBlock(x, y, mask0, mask1, args); - } - } - } - -private: - template - FORCEINLINE static void DrawBlock(int destX, int destY, uint32_t mask0, uint32_t mask1, const TriDrawTriangleArgs *args) - { - using namespace TriScreenDrawerModes; - - 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(); - - auto lights = args->uniforms->Lights(); - auto num_lights = args->uniforms->NumLights(); - FVector3 worldnormal = args->uniforms->Normal(); - uint32_t dynlightcolor = args->uniforms->DynLightColor(); - - // Calculate gradients - const ShadedTriVertex &v1 = *args->v1; - ScreenTriangleStepVariables gradientX = args->gradientX; - ScreenTriangleStepVariables gradientY = args->gradientY; - ScreenTriangleStepVariables blockPosY; - blockPosY.W = v1.w + gradientX.W * (destX - v1.x) + gradientY.W * (destY - v1.y); - blockPosY.U = v1.u * v1.w + gradientX.U * (destX - v1.x) + gradientY.U * (destY - v1.y); - blockPosY.V = v1.v * v1.w + gradientX.V * (destX - v1.x) + gradientY.V * (destY - v1.y); - blockPosY.WorldX = v1.worldX * v1.w + gradientX.WorldX * (destX - v1.x) + gradientY.WorldX * (destY - v1.y); - blockPosY.WorldY = v1.worldY * v1.w + gradientX.WorldY * (destX - v1.x) + gradientY.WorldY * (destY - v1.y); - blockPosY.WorldZ = v1.worldZ * v1.w + gradientX.WorldZ * (destX - v1.x) + gradientY.WorldZ * (destY - v1.y); - gradientX.W *= 8.0f; - gradientX.U *= 8.0f; - gradientX.V *= 8.0f; - gradientX.WorldX *= 8.0f; - gradientX.WorldY *= 8.0f; - gradientX.WorldZ *= 8.0f; - - // Output - uint32_t * RESTRICT destOrg = (uint32_t*)args->dest; - int pitch = args->pitch; - uint32_t *dest = destOrg + destX + destY * pitch; - - // Light - uint32_t light = args->uniforms->Light(); - 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->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) - { - oneU = ((0x800000 + texWidth - 1) / texWidth) * 2 + 1; - oneV = ((0x800000 + texHeight - 1) / texHeight) * 2 + 1; - } - else - { - oneU = 0; - oneV = 0; - } - - // Shade constants - int inv_desaturate; - BgraColor shade_fade, shade_light; - int desaturate; - if (ShadeModeT::Mode == (int)ShadeMode::Advanced) - { - shade_fade.r = args->uniforms->ShadeFadeRed(); - shade_fade.g = args->uniforms->ShadeFadeGreen(); - shade_fade.b = args->uniforms->ShadeFadeBlue(); - shade_light.r = args->uniforms->ShadeLightRed(); - shade_light.g = args->uniforms->ShadeLightGreen(); - shade_light.b = args->uniforms->ShadeLightBlue(); - desaturate = args->uniforms->ShadeDesaturate(); - inv_desaturate = 256 - desaturate; - } - else - { - inv_desaturate = 0; - shade_fade.r = 0; - shade_fade.g = 0; - shade_fade.b = 0; - shade_light.r = 0; - shade_light.g = 0; - shade_light.b = 0; - desaturate = 0; - } - - if (mask0 == 0xffffffff && mask1 == 0xffffffff) - { - for (int y = 0; y < 8; y++) - { - float rcpW = 0x01000000 / blockPosY.W; - int32_t posU = (int32_t)(blockPosY.U * rcpW); - int32_t posV = (int32_t)(blockPosY.V * rcpW); - - fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask); - - FVector3 worldpos = FVector3(blockPosY.WorldX, blockPosY.WorldY, blockPosY.WorldZ) / blockPosY.W; - BgraColor dynlight = CalcDynamicLight(lights, num_lights, worldpos, worldnormal, dynlightcolor); - - ScreenTriangleStepVariables blockPosX = blockPosY; - blockPosX.W += gradientX.W; - blockPosX.U += gradientX.U; - blockPosX.V += gradientX.V; - blockPosX.WorldX += gradientX.WorldX; - blockPosX.WorldY += gradientX.WorldY; - blockPosX.WorldZ += gradientX.WorldZ; - - rcpW = 0x01000000 / blockPosX.W; - int32_t nextU = (int32_t)(blockPosX.U * rcpW); - int32_t nextV = (int32_t)(blockPosX.V * rcpW); - int32_t stepU = (nextU - posU) / 8; - int32_t stepV = (nextV - posV) / 8; - - fixed_t lightnext = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosX.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - fixed_t lightstep = (lightnext - lightpos) / 8; - lightstep = lightstep & lightmask; - - worldpos = FVector3(blockPosX.WorldX, blockPosX.WorldY, blockPosX.WorldZ) / blockPosX.W; - BgraColor dynlightnext = CalcDynamicLight(lights, num_lights, worldpos, worldnormal, dynlightcolor); - BgraColor dynlightstep; - dynlightstep.r = int32_t(dynlightnext.r - dynlight.r) >> 3; - dynlightstep.g = int32_t(dynlightnext.g - dynlight.g) >> 3; - dynlightstep.b = int32_t(dynlightnext.b - dynlight.b) >> 3; - - for (int ix = 0; ix < 8; ix++) - { - // Load bgcolor - BgraColor bgcolor; - if (BlendT::Mode != (int)BlendModes::Opaque) - bgcolor = dest[ix]; - else - bgcolor = 0; - - // Sample fgcolor - if (SamplerT::Mode == (int)Samplers::FogBoundary) color = dest[ix]; - unsigned int ifgcolor = Sample32(posU, posV, texPixels, texWidth, texHeight, oneU, oneV, color, translation); - unsigned int ifgshade = SampleShade32(posU, posV, texPixels, texWidth, texHeight, destX + ix, destY + y); - posU += stepU; - posV += stepV; - - // Setup light - int lightpos0 = lightpos >> 8; - lightpos += lightstep; - BgraColor mlight; - mlight.r = lightpos0; - mlight.g = lightpos0; - mlight.b = lightpos0; - - BgraColor shade_fade_lit; - if (ShadeModeT::Mode == (int)ShadeMode::Advanced) - { - uint32_t inv_light = 256 - lightpos0; - shade_fade_lit.r = shade_fade.r * inv_light; - shade_fade_lit.g = shade_fade.g * inv_light; - shade_fade_lit.b = shade_fade.b * inv_light; - } - else - { - shade_fade_lit.r = 0; - shade_fade_lit.g = 0; - shade_fade_lit.b = 0; - } - - // Shade and blend - BgraColor fgcolor = Shade32(ifgcolor, mlight, desaturate, inv_desaturate, shade_fade_lit, shade_light, dynlight); - BgraColor outcolor = Blend32(fgcolor, bgcolor, ifgcolor, ifgshade, srcalpha, destalpha); - - // Store result - dest[ix] = outcolor; - - dynlight.r = MAX(dynlight.r + dynlightstep.r, 0); - dynlight.g = MAX(dynlight.g + dynlightstep.g, 0); - dynlight.b = MAX(dynlight.b + dynlightstep.b, 0); - } - - blockPosY.W += gradientY.W; - blockPosY.U += gradientY.U; - blockPosY.V += gradientY.V; - blockPosY.WorldX += gradientY.WorldX; - blockPosY.WorldY += gradientY.WorldY; - blockPosY.WorldZ += gradientY.WorldZ; - - dest += pitch; - } - } - else - { - // mask0 loop: - for (int y = 0; y < 4; y++) - { - float rcpW = 0x01000000 / blockPosY.W; - int32_t posU = (int32_t)(blockPosY.U * rcpW); - int32_t posV = (int32_t)(blockPosY.V * rcpW); - - fixed_t lightpos = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask); - - FVector3 worldpos = FVector3(blockPosY.WorldX, blockPosY.WorldY, blockPosY.WorldZ) / blockPosY.W; - BgraColor dynlight = CalcDynamicLight(lights, num_lights, worldpos, worldnormal, dynlightcolor); - - ScreenTriangleStepVariables blockPosX = blockPosY; - blockPosX.W += gradientX.W; - blockPosX.U += gradientX.U; - blockPosX.V += gradientX.V; - blockPosX.WorldX += gradientX.WorldX; - blockPosX.WorldY += gradientX.WorldY; - blockPosX.WorldZ += gradientX.WorldZ; - - rcpW = 0x01000000 / blockPosX.W; - int32_t nextU = (int32_t)(blockPosX.U * rcpW); - int32_t nextV = (int32_t)(blockPosX.V * rcpW); - int32_t stepU = (nextU - posU) / 8; - int32_t stepV = (nextV - posV) / 8; - - fixed_t lightnext = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosX.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - fixed_t lightstep = (lightnext - lightpos) / 8; - lightstep = lightstep & lightmask; - - worldpos = FVector3(blockPosX.WorldX, blockPosX.WorldY, blockPosX.WorldZ) / blockPosX.W; - BgraColor dynlightnext = CalcDynamicLight(lights, num_lights, worldpos, worldnormal, dynlightcolor); - BgraColor dynlightstep; - dynlightstep.r = int32_t(dynlightnext.r - dynlight.r) >> 3; - dynlightstep.g = int32_t(dynlightnext.g - dynlight.g) >> 3; - dynlightstep.b = int32_t(dynlightnext.b - dynlight.b) >> 3; - - for (int x = 0; x < 8; x++) - { - // Load bgcolor - BgraColor bgcolor; - if (BlendT::Mode != (int)BlendModes::Opaque) - { - if (mask0 & (1 << 31)) bgcolor = dest[x]; - } - else - bgcolor = 0; - - // Sample fgcolor - if (SamplerT::Mode == (int)Samplers::FogBoundary && (mask0 & (1 << 31))) color = dest[x]; - unsigned int ifgcolor = Sample32(posU, posV, texPixels, texWidth, texHeight, oneU, oneV, color, translation); - unsigned int ifgshade = SampleShade32(posU, posV, texPixels, texWidth, texHeight, destX + x, destY + y); - posU += stepU; - posV += stepV; - - // Setup light - int lightpos0 = lightpos >> 8; - lightpos += lightstep; - BgraColor mlight; - mlight.r = lightpos0; - mlight.g = lightpos0; - mlight.b = lightpos0; - - BgraColor shade_fade_lit; - if (ShadeModeT::Mode == (int)ShadeMode::Advanced) - { - uint32_t inv_light = 256 - lightpos0; - shade_fade_lit.r = shade_fade.r * inv_light; - shade_fade_lit.g = shade_fade.g * inv_light; - shade_fade_lit.b = shade_fade.b * inv_light; - } - else - { - shade_fade_lit.r = 0; - shade_fade_lit.g = 0; - shade_fade_lit.b = 0; - } - - // Shade and blend - BgraColor fgcolor = Shade32(ifgcolor, mlight, desaturate, inv_desaturate, shade_fade_lit, shade_light, dynlight); - BgraColor outcolor = Blend32(fgcolor, bgcolor, ifgcolor, ifgshade, srcalpha, destalpha); - - // Store result - if (mask0 & (1 << 31)) dest[x] = outcolor; - - mask0 <<= 1; - - dynlight.r = MAX(dynlight.r + dynlightstep.r, 0); - dynlight.g = MAX(dynlight.g + dynlightstep.g, 0); - dynlight.b = MAX(dynlight.b + dynlightstep.b, 0); - } - - blockPosY.W += gradientY.W; - blockPosY.U += gradientY.U; - blockPosY.V += gradientY.V; - blockPosY.WorldX += gradientY.WorldX; - blockPosY.WorldY += gradientY.WorldY; - blockPosY.WorldZ += gradientY.WorldZ; - - dest += pitch; - } - - // mask1 loop: - for (int y = 0; y < 4; y++) - { - float rcpW = 0x01000000 / blockPosY.W; - int32_t posU = (int32_t)(blockPosY.U * rcpW); - int32_t posV = (int32_t)(blockPosY.V * rcpW); - - fixed_t lightpos = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask); - - FVector3 worldpos = FVector3(blockPosY.WorldX, blockPosY.WorldY, blockPosY.WorldZ) / blockPosY.W; - BgraColor dynlight = CalcDynamicLight(lights, num_lights, worldpos, worldnormal, dynlightcolor); - - ScreenTriangleStepVariables blockPosX = blockPosY; - blockPosX.W += gradientX.W; - blockPosX.U += gradientX.U; - blockPosX.V += gradientX.V; - blockPosX.WorldX += gradientX.WorldX; - blockPosX.WorldY += gradientX.WorldY; - blockPosX.WorldZ += gradientX.WorldZ; - - rcpW = 0x01000000 / blockPosX.W; - int32_t nextU = (int32_t)(blockPosX.U * rcpW); - int32_t nextV = (int32_t)(blockPosX.V * rcpW); - int32_t stepU = (nextU - posU) / 8; - int32_t stepV = (nextV - posV) / 8; - - fixed_t lightnext = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosX.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - fixed_t lightstep = (lightnext - lightpos) / 8; - lightstep = lightstep & lightmask; - - worldpos = FVector3(blockPosX.WorldX, blockPosX.WorldY, blockPosX.WorldZ) / blockPosX.W; - BgraColor dynlightnext = CalcDynamicLight(lights, num_lights, worldpos, worldnormal, dynlightcolor); - BgraColor dynlightstep; - dynlightstep.r = int32_t(dynlightnext.r - dynlight.r) >> 3; - dynlightstep.g = int32_t(dynlightnext.g - dynlight.g) >> 3; - dynlightstep.b = int32_t(dynlightnext.b - dynlight.b) >> 3; - - for (int x = 0; x < 8; x++) - { - // Load bgcolor - BgraColor bgcolor; - if (BlendT::Mode != (int)BlendModes::Opaque) - { - if (mask1 & (1 << 31)) bgcolor = dest[x]; - } - else - bgcolor = 0; - - // Sample fgcolor - if (SamplerT::Mode == (int)Samplers::FogBoundary && (mask1 & (1 << 31))) color = dest[x]; - unsigned int ifgcolor = Sample32(posU, posV, texPixels, texWidth, texHeight, oneU, oneV, color, translation); - unsigned int ifgshade = SampleShade32(posU, posV, texPixels, texWidth, texHeight, destX + x, destY + 4 + y); - posU += stepU; - posV += stepV; - - // Setup light - int lightpos0 = lightpos >> 8; - lightpos += lightstep; - BgraColor mlight; - mlight.r = lightpos0; - mlight.g = lightpos0; - mlight.b = lightpos0; - - BgraColor shade_fade_lit; - if (ShadeModeT::Mode == (int)ShadeMode::Advanced) - { - uint32_t inv_light = 256 - lightpos0; - shade_fade_lit.r = shade_fade.r * inv_light; - shade_fade_lit.g = shade_fade.g * inv_light; - shade_fade_lit.b = shade_fade.b * inv_light; - } - else - { - shade_fade_lit.r = 0; - shade_fade_lit.g = 0; - shade_fade_lit.b = 0; - } - - // Shade and blend - BgraColor fgcolor = Shade32(ifgcolor, mlight, desaturate, inv_desaturate, shade_fade_lit, shade_light, dynlight); - BgraColor outcolor = Blend32(fgcolor, bgcolor, ifgcolor, ifgshade, srcalpha, destalpha); - - // Store result - if (mask1 & (1 << 31)) dest[x] = outcolor; - - mask1 <<= 1; - - dynlight.r = MAX(dynlight.r + dynlightstep.r, 0); - dynlight.g = MAX(dynlight.g + dynlightstep.g, 0); - dynlight.b = MAX(dynlight.b + dynlightstep.b, 0); - } - - blockPosY.W += gradientY.W; - blockPosY.U += gradientY.U; - blockPosY.V += gradientY.V; - blockPosY.WorldX += gradientY.WorldX; - blockPosY.WorldY += gradientY.WorldY; - blockPosY.WorldZ += gradientY.WorldZ; - - dest += pitch; - } - } - } -}; - template class RectScreenDrawer32 { diff --git a/src/polyrenderer/drawers/poly_drawer32_sse2.h b/src/polyrenderer/drawers/poly_drawer32_sse2.h index 11d08c59c..4685dd07c 100644 --- a/src/polyrenderer/drawers/poly_drawer32_sse2.h +++ b/src/polyrenderer/drawers/poly_drawer32_sse2.h @@ -347,461 +347,6 @@ namespace TriScreenDrawerModes } } -template -class TriScreenDrawer32 -{ -public: - static void Execute(int x, int y, uint32_t mask0, uint32_t mask1, const TriDrawTriangleArgs *args) - { - using namespace TriScreenDrawerModes; - - bool is_simple_shade = args->uniforms->SimpleShade(); - - if (SamplerT::Mode == (int)Samplers::Texture) - { - bool is_nearest_filter = args->uniforms->NearestFilter(); - - if (is_simple_shade) - { - if (is_nearest_filter) - DrawBlock(x, y, mask0, mask1, args); - else - DrawBlock(x, y, mask0, mask1, args); - } - else - { - if (is_nearest_filter) - DrawBlock(x, y, mask0, mask1, args); - else - DrawBlock(x, y, mask0, mask1, args); - } - } - else if (SamplerT::Mode == (int)Samplers::Fuzz) - { - DrawBlock(x, y, mask0, mask1, args); - } - else // no linear filtering for translated, shaded, stencil, fill or skycap - { - if (is_simple_shade) - { - DrawBlock(x, y, mask0, mask1, args); - } - else - { - DrawBlock(x, y, mask0, mask1, args); - } - } - } - -private: - template - FORCEINLINE static void VECTORCALL DrawBlock(int destX, int destY, uint32_t mask0, uint32_t mask1, const TriDrawTriangleArgs *args) - { - using namespace TriScreenDrawerModes; - - 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(); - - auto lights = args->uniforms->Lights(); - auto num_lights = args->uniforms->NumLights(); - __m128 worldnormal = _mm_setr_ps(args->uniforms->Normal().X, args->uniforms->Normal().Y, args->uniforms->Normal().Z, 0.0f); - uint32_t dynlightcolor = args->uniforms->DynLightColor(); - - // Calculate gradients - const ShadedTriVertex &v1 = *args->v1; - ScreenTriangleStepVariables gradientX = args->gradientX; - ScreenTriangleStepVariables gradientY = args->gradientY; - ScreenTriangleStepVariables blockPosY; - blockPosY.W = v1.w + gradientX.W * (destX - v1.x) + gradientY.W * (destY - v1.y); - blockPosY.U = v1.u * v1.w + gradientX.U * (destX - v1.x) + gradientY.U * (destY - v1.y); - blockPosY.V = v1.v * v1.w + gradientX.V * (destX - v1.x) + gradientY.V * (destY - v1.y); - blockPosY.WorldX = v1.worldX * v1.w + gradientX.WorldX * (destX - v1.x) + gradientY.WorldX * (destY - v1.y); - blockPosY.WorldY = v1.worldY * v1.w + gradientX.WorldY * (destX - v1.x) + gradientY.WorldY * (destY - v1.y); - blockPosY.WorldZ = v1.worldZ * v1.w + gradientX.WorldZ * (destX - v1.x) + gradientY.WorldZ * (destY - v1.y); - gradientX.W *= 8.0f; - gradientX.U *= 8.0f; - gradientX.V *= 8.0f; - gradientX.WorldX *= 8.0f; - gradientX.WorldY *= 8.0f; - gradientX.WorldZ *= 8.0f; - - // Output - uint32_t * RESTRICT destOrg = (uint32_t*)args->dest; - int pitch = args->pitch; - uint32_t *dest = destOrg + destX + destY * pitch; - - // Light - uint32_t light = args->uniforms->Light(); - 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->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) - { - oneU = ((0x800000 + texWidth - 1) / texWidth) * 2 + 1; - oneV = ((0x800000 + texHeight - 1) / texHeight) * 2 + 1; - } - else - { - oneU = 0; - oneV = 0; - } - - // Shade constants - __m128i inv_desaturate, shade_fade, shade_light; - int desaturate; - if (ShadeModeT::Mode == (int)ShadeMode::Advanced) - { - 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 - { - inv_desaturate = _mm_setzero_si128(); - shade_fade = _mm_setzero_si128(); - shade_fade = _mm_setzero_si128(); - shade_light = _mm_setzero_si128(); - desaturate = 0; - } - - if (mask0 == 0xffffffff && mask1 == 0xffffffff) - { - for (int y = 0; y < 8; y++) - { - float rcpW = 0x01000000 / blockPosY.W; - int32_t posU = (int32_t)(blockPosY.U * rcpW); - int32_t posV = (int32_t)(blockPosY.V * rcpW); - - fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask); - - __m128 mrcpW = _mm_set1_ps(1.0f / blockPosY.W); - __m128 worldpos = _mm_mul_ps(_mm_loadu_ps(&blockPosY.WorldX), mrcpW); - __m128i dynlight = CalcDynamicLight(lights, num_lights, worldpos, worldnormal, dynlightcolor); - - ScreenTriangleStepVariables blockPosX = blockPosY; - blockPosX.W += gradientX.W; - blockPosX.U += gradientX.U; - blockPosX.V += gradientX.V; - blockPosX.WorldX += gradientX.WorldX; - blockPosX.WorldY += gradientX.WorldY; - blockPosX.WorldZ += gradientX.WorldZ; - - rcpW = 0x01000000 / blockPosX.W; - int32_t nextU = (int32_t)(blockPosX.U * rcpW); - int32_t nextV = (int32_t)(blockPosX.V * rcpW); - int32_t stepU = (nextU - posU) / 8; - int32_t stepV = (nextV - posV) / 8; - - fixed_t lightnext = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosX.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - fixed_t lightstep = (lightnext - lightpos) / 8; - lightstep = lightstep & lightmask; - - mrcpW = _mm_set1_ps(1.0f / blockPosX.W); - worldpos = _mm_mul_ps(_mm_loadu_ps(&blockPosX.WorldX), mrcpW); - __m128i dynlightnext = CalcDynamicLight(lights, num_lights, worldpos, worldnormal, dynlightcolor); - __m128i dynlightstep = _mm_srai_epi16(_mm_sub_epi16(dynlightnext, dynlight), 3); - dynlight = _mm_max_epi16(_mm_min_epi16(_mm_add_epi16(dynlight, _mm_and_si128(dynlightstep, _mm_set_epi32(0xffff,0xffff,0,0))), _mm_set1_epi16(256)), _mm_setzero_si128()); - dynlightstep = _mm_slli_epi16(dynlightstep, 1); - - for (int ix = 0; ix < 4; ix++) - { - // Load bgcolor - __m128i bgcolor; - if (BlendT::Mode != (int)BlendModes::Opaque) - bgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(dest + ix * 2)), _mm_setzero_si128()); - else - bgcolor = _mm_setzero_si128(); - - // Sample fgcolor - unsigned int ifgcolor[2], ifgshade[2]; - if (SamplerT::Mode == (int)Samplers::FogBoundary) color = dest[ix * 2]; - ifgcolor[0] = Sample32(posU, posV, texPixels, texWidth, texHeight, oneU, oneV, color, translation); - ifgshade[0] = SampleShade32(posU, posV, texPixels, texWidth, texHeight, destX + ix * 2, destY + y); - posU += stepU; - posV += stepV; - - if (SamplerT::Mode == (int)Samplers::FogBoundary) color = dest[ix * 2 + 1]; - ifgcolor[1] = Sample32(posU, posV, texPixels, texWidth, texHeight, oneU, oneV, color, translation); - ifgshade[1] = SampleShade32(posU, posV, texPixels, texWidth, texHeight, destX + ix * 2 + 1, destY + y); - posU += stepU; - posV += stepV; - - // Setup light - int lightpos0 = lightpos >> 8; - lightpos += lightstep; - int lightpos1 = lightpos >> 8; - lightpos += lightstep; - __m128i mlight = _mm_set_epi16(256, lightpos1, lightpos1, lightpos1, 256, lightpos0, lightpos0, lightpos0); - - __m128i shade_fade_lit; - if (ShadeModeT::Mode == (int)ShadeMode::Advanced) - { - __m128i inv_light = _mm_sub_epi16(_mm_set_epi16(0, 256, 256, 256, 0, 256, 256, 256), mlight); - shade_fade_lit = _mm_mullo_epi16(shade_fade, inv_light); - } - else - { - shade_fade_lit = _mm_setzero_si128(); - } - - // Shade and blend - __m128i fgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)ifgcolor), _mm_setzero_si128()); - fgcolor = Shade32(fgcolor, mlight, ifgcolor[0], ifgcolor[1], desaturate, inv_desaturate, shade_fade_lit, shade_light, dynlight); - __m128i outcolor = Blend32(fgcolor, bgcolor, ifgcolor[0], ifgcolor[1], ifgshade[0], ifgshade[1], srcalpha, destalpha); - - // Store result - _mm_storel_epi64((__m128i*)(dest + ix * 2), outcolor); - - dynlight = _mm_max_epi16(_mm_min_epi16(_mm_add_epi16(dynlight, dynlightstep), _mm_set1_epi16(256)), _mm_setzero_si128()); - } - - blockPosY.W += gradientY.W; - blockPosY.U += gradientY.U; - blockPosY.V += gradientY.V; - blockPosY.WorldX += gradientY.WorldX; - blockPosY.WorldY += gradientY.WorldY; - blockPosY.WorldZ += gradientY.WorldZ; - - dest += pitch; - } - } - else - { - // mask0 loop: - for (int y = 0; y < 4; y++) - { - float rcpW = 0x01000000 / blockPosY.W; - int32_t posU = (int32_t)(blockPosY.U * rcpW); - int32_t posV = (int32_t)(blockPosY.V * rcpW); - - fixed_t lightpos = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask); - - __m128 mrcpW = _mm_set1_ps(1.0f / blockPosY.W); - __m128 worldpos = _mm_mul_ps(_mm_loadu_ps(&blockPosY.WorldX), mrcpW); - __m128i dynlight = CalcDynamicLight(lights, num_lights, worldpos, worldnormal, dynlightcolor); - - ScreenTriangleStepVariables blockPosX = blockPosY; - blockPosX.W += gradientX.W; - blockPosX.U += gradientX.U; - blockPosX.V += gradientX.V; - blockPosX.WorldX += gradientX.WorldX; - blockPosX.WorldY += gradientX.WorldY; - blockPosX.WorldZ += gradientX.WorldZ; - - rcpW = 0x01000000 / blockPosX.W; - int32_t nextU = (int32_t)(blockPosX.U * rcpW); - int32_t nextV = (int32_t)(blockPosX.V * rcpW); - int32_t stepU = (nextU - posU) / 8; - int32_t stepV = (nextV - posV) / 8; - - fixed_t lightnext = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosX.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - fixed_t lightstep = (lightnext - lightpos) / 8; - lightstep = lightstep & lightmask; - - mrcpW = _mm_set1_ps(1.0f / blockPosX.W); - worldpos = _mm_mul_ps(_mm_loadu_ps(&blockPosX.WorldX), mrcpW); - __m128i dynlightnext = CalcDynamicLight(lights, num_lights, worldpos, worldnormal, dynlightcolor); - __m128i dynlightstep = _mm_srai_epi16(_mm_sub_epi16(dynlightnext, dynlight), 3); - dynlight = _mm_max_epi16(_mm_min_epi16(_mm_add_epi16(dynlight, _mm_and_si128(dynlightstep, _mm_set_epi32(0xffff, 0xffff, 0, 0))), _mm_set1_epi16(256)), _mm_setzero_si128()); - dynlightstep = _mm_slli_epi16(dynlightstep, 1); - - for (int x = 0; x < 4; x++) - { - // Load bgcolor - uint32_t desttmp[2]; - __m128i bgcolor; - if (BlendT::Mode != (int)BlendModes::Opaque) - { - if (mask0 & (1 << 31)) desttmp[0] = dest[x * 2]; - if (mask0 & (1 << 30)) desttmp[1] = dest[x * 2 + 1]; - bgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)desttmp), _mm_setzero_si128()); - } - else - bgcolor = _mm_setzero_si128(); - - // Sample fgcolor - unsigned int ifgcolor[2], ifgshade[2]; - if (SamplerT::Mode == (int)Samplers::FogBoundary) color = dest[x * 2]; - ifgcolor[0] = Sample32(posU, posV, texPixels, texWidth, texHeight, oneU, oneV, color, translation); - ifgshade[0] = SampleShade32(posU, posV, texPixels, texWidth, texHeight, destX + x * 2, destY + y); - posU += stepU; - posV += stepV; - - if (SamplerT::Mode == (int)Samplers::FogBoundary) color = dest[x * 2 + 1]; - ifgcolor[1] = Sample32(posU, posV, texPixels, texWidth, texHeight, oneU, oneV, color, translation); - ifgshade[1] = SampleShade32(posU, posV, texPixels, texWidth, texHeight, destX + x * 2 + 1, destY + y); - posU += stepU; - posV += stepV; - - // Setup light - int lightpos0 = lightpos >> 8; - lightpos += lightstep; - int lightpos1 = lightpos >> 8; - lightpos += lightstep; - __m128i mlight = _mm_set_epi16(256, lightpos1, lightpos1, lightpos1, 256, lightpos0, lightpos0, lightpos0); - - __m128i shade_fade_lit; - if (ShadeModeT::Mode == (int)ShadeMode::Advanced) - { - __m128i inv_light = _mm_sub_epi16(_mm_set_epi16(0, 256, 256, 256, 0, 256, 256, 256), mlight); - shade_fade_lit = _mm_mullo_epi16(shade_fade, inv_light); - } - else - { - shade_fade_lit = _mm_setzero_si128(); - } - - // Shade and blend - __m128i fgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)ifgcolor), _mm_setzero_si128()); - fgcolor = Shade32(fgcolor, mlight, ifgcolor[0], ifgcolor[1], desaturate, inv_desaturate, shade_fade_lit, shade_light, dynlight); - __m128i outcolor = Blend32(fgcolor, bgcolor, ifgcolor[0], ifgcolor[1], ifgshade[0], ifgshade[1], srcalpha, destalpha); - - // Store result - _mm_storel_epi64((__m128i*)desttmp, outcolor); - if (mask0 & (1 << 31)) dest[x * 2] = desttmp[0]; - if (mask0 & (1 << 30)) dest[x * 2 + 1] = desttmp[1]; - - dynlight = _mm_max_epi16(_mm_min_epi16(_mm_add_epi16(dynlight, dynlightstep), _mm_set1_epi16(256)), _mm_setzero_si128()); - - mask0 <<= 2; - } - - blockPosY.W += gradientY.W; - blockPosY.U += gradientY.U; - blockPosY.V += gradientY.V; - blockPosY.WorldX += gradientY.WorldX; - blockPosY.WorldY += gradientY.WorldY; - blockPosY.WorldZ += gradientY.WorldZ; - - dest += pitch; - } - - // mask1 loop: - for (int y = 0; y < 4; y++) - { - float rcpW = 0x01000000 / blockPosY.W; - int32_t posU = (int32_t)(blockPosY.U * rcpW); - int32_t posV = (int32_t)(blockPosY.V * rcpW); - - fixed_t lightpos = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask); - - __m128 mrcpW = _mm_set1_ps(1.0f / blockPosY.W); - __m128 worldpos = _mm_mul_ps(_mm_loadu_ps(&blockPosY.WorldX), mrcpW); - __m128i dynlight = CalcDynamicLight(lights, num_lights, worldpos, worldnormal, dynlightcolor); - - ScreenTriangleStepVariables blockPosX = blockPosY; - blockPosX.W += gradientX.W; - blockPosX.U += gradientX.U; - blockPosX.V += gradientX.V; - blockPosX.WorldX += gradientX.WorldX; - blockPosX.WorldY += gradientX.WorldY; - blockPosX.WorldZ += gradientX.WorldZ; - - rcpW = 0x01000000 / blockPosX.W; - int32_t nextU = (int32_t)(blockPosX.U * rcpW); - int32_t nextV = (int32_t)(blockPosX.V * rcpW); - int32_t stepU = (nextU - posU) / 8; - int32_t stepV = (nextV - posV) / 8; - - fixed_t lightnext = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosX.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - fixed_t lightstep = (lightnext - lightpos) / 8; - lightstep = lightstep & lightmask; - - mrcpW = _mm_set1_ps(1.0f / blockPosX.W); - worldpos = _mm_mul_ps(_mm_loadu_ps(&blockPosX.WorldX), mrcpW); - __m128i dynlightnext = CalcDynamicLight(lights, num_lights, worldpos, worldnormal, dynlightcolor); - __m128i dynlightstep = _mm_srai_epi16(_mm_sub_epi16(dynlightnext, dynlight), 3); - dynlight = _mm_max_epi16(_mm_min_epi16(_mm_add_epi16(dynlight, _mm_and_si128(dynlightstep, _mm_set_epi32(0xffff, 0xffff, 0, 0))), _mm_set1_epi16(256)), _mm_setzero_si128()); - dynlightstep = _mm_slli_epi16(dynlightstep, 1); - - for (int x = 0; x < 4; x++) - { - // Load bgcolor - uint32_t desttmp[2]; - __m128i bgcolor; - if (BlendT::Mode != (int)BlendModes::Opaque) - { - if (mask1 & (1 << 31)) desttmp[0] = dest[x * 2]; - if (mask1 & (1 << 30)) desttmp[1] = dest[x * 2 + 1]; - bgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)desttmp), _mm_setzero_si128()); - } - else - bgcolor = _mm_setzero_si128(); - - // Sample fgcolor - unsigned int ifgcolor[2], ifgshade[2]; - if (SamplerT::Mode == (int)Samplers::FogBoundary && (mask1 & (1 << 31))) color = dest[x * 2]; - ifgcolor[0] = Sample32(posU, posV, texPixels, texWidth, texHeight, oneU, oneV, color, translation); - ifgshade[0] = SampleShade32(posU, posV, texPixels, texWidth, texHeight, destX + x * 2, destY + 4 + y); - posU += stepU; - posV += stepV; - - if (SamplerT::Mode == (int)Samplers::FogBoundary && (mask1 & (1 << 30))) color = dest[x * 2 + 1]; - ifgcolor[1] = Sample32(posU, posV, texPixels, texWidth, texHeight, oneU, oneV, color, translation); - ifgshade[1] = SampleShade32(posU, posV, texPixels, texWidth, texHeight, destX + x * 2 + 1, destY + 4 + y); - posU += stepU; - posV += stepV; - - // Setup light - int lightpos0 = lightpos >> 8; - lightpos += lightstep; - int lightpos1 = lightpos >> 8; - lightpos += lightstep; - __m128i mlight = _mm_set_epi16(256, lightpos1, lightpos1, lightpos1, 256, lightpos0, lightpos0, lightpos0); - - __m128i shade_fade_lit; - if (ShadeModeT::Mode == (int)ShadeMode::Advanced) - { - __m128i inv_light = _mm_sub_epi16(_mm_set_epi16(0, 256, 256, 256, 0, 256, 256, 256), mlight); - shade_fade_lit = _mm_mullo_epi16(shade_fade, inv_light); - } - else - { - shade_fade_lit = _mm_setzero_si128(); - } - - // Shade and blend - __m128i fgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)ifgcolor), _mm_setzero_si128()); - fgcolor = Shade32(fgcolor, mlight, ifgcolor[0], ifgcolor[1], desaturate, inv_desaturate, shade_fade_lit, shade_light, dynlight); - __m128i outcolor = Blend32(fgcolor, bgcolor, ifgcolor[0], ifgcolor[1], ifgshade[0], ifgshade[1], srcalpha, destalpha); - - // Store result - _mm_storel_epi64((__m128i*)desttmp, outcolor); - if (mask1 & (1 << 31)) dest[x * 2] = desttmp[0]; - if (mask1 & (1 << 30)) dest[x * 2 + 1] = desttmp[1]; - - dynlight = _mm_max_epi16(_mm_min_epi16(_mm_add_epi16(dynlight, dynlightstep), _mm_set1_epi16(256)), _mm_setzero_si128()); - - mask1 <<= 2; - } - - blockPosY.W += gradientY.W; - blockPosY.U += gradientY.U; - blockPosY.V += gradientY.V; - blockPosY.WorldX += gradientY.WorldX; - blockPosY.WorldY += gradientY.WorldY; - blockPosY.WorldZ += gradientY.WorldZ; - - dest += pitch; - } - } - } -}; - template class RectScreenDrawer32 { diff --git a/src/polyrenderer/drawers/poly_drawer8.h b/src/polyrenderer/drawers/poly_drawer8.h index d87b16194..1db272885 100644 --- a/src/polyrenderer/drawers/poly_drawer8.h +++ b/src/polyrenderer/drawers/poly_drawer8.h @@ -225,206 +225,6 @@ namespace TriScreenDrawerModes } } -template -class TriScreenDrawer8 -{ -public: - static void Execute(int destX, int destY, uint32_t mask0, uint32_t mask1, const TriDrawTriangleArgs *args) - { - using namespace TriScreenDrawerModes; - - bool is_fixed_light = args->uniforms->FixedLight(); - uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff; - auto colormaps = args->uniforms->BaseColormap(); - uint32_t srcalpha = args->uniforms->SrcAlpha(); - uint32_t destalpha = args->uniforms->DestAlpha(); - - // Calculate gradients - const ShadedTriVertex &v1 = *args->v1; - ScreenTriangleStepVariables gradientX = args->gradientX; - ScreenTriangleStepVariables gradientY = args->gradientY; - ScreenTriangleStepVariables blockPosY; - blockPosY.W = v1.w + gradientX.W * (destX - v1.x) + gradientY.W * (destY - v1.y); - blockPosY.U = v1.u * v1.w + gradientX.U * (destX - v1.x) + gradientY.U * (destY - v1.y); - blockPosY.V = v1.v * v1.w + gradientX.V * (destX - v1.x) + gradientY.V * (destY - v1.y); - gradientX.W *= 8.0f; - gradientX.U *= 8.0f; - gradientX.V *= 8.0f; - - // Output - uint8_t * RESTRICT destOrg = args->dest; - int pitch = args->pitch; - uint8_t *dest = destOrg + destX + destY * pitch; - - // Light - uint32_t light = args->uniforms->Light(); - 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->uniforms->Translation(); - const uint8_t * RESTRICT texPixels = args->uniforms->TexturePixels(); - uint32_t texWidth = args->uniforms->TextureWidth(); - uint32_t texHeight = args->uniforms->TextureHeight(); - - if (mask0 == 0xffffffff && mask1 == 0xffffffff) - { - for (int y = 0; y < 8; y++) - { - float rcpW = 0x01000000 / blockPosY.W; - int32_t posU = (int32_t)(blockPosY.U * rcpW); - int32_t posV = (int32_t)(blockPosY.V * rcpW); - - fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask); - - ScreenTriangleStepVariables blockPosX = blockPosY; - blockPosX.W += gradientX.W; - blockPosX.U += gradientX.U; - blockPosX.V += gradientX.V; - - rcpW = 0x01000000 / blockPosX.W; - int32_t nextU = (int32_t)(blockPosX.U * rcpW); - int32_t nextV = (int32_t)(blockPosX.V * rcpW); - int32_t stepU = (nextU - posU) / 8; - int32_t stepV = (nextV - posV) / 8; - - fixed_t lightnext = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosX.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - fixed_t lightstep = (lightnext - lightpos) / 8; - lightstep = lightstep & lightmask; - - for (int ix = 0; ix < 8; ix++) - { - int lightshade = lightpos >> 8; - uint8_t bgcolor = dest[ix]; - if (SamplerT::Mode == (int)Samplers::FogBoundary) color = bgcolor; - uint8_t fgcolor = Sample8(posU, posV, texPixels, texWidth, texHeight, color, translation); - uint32_t fgshade = SampleShade8(posU, posV, texPixels, texWidth, texHeight, destX + ix, destY + y); - if (SamplerT::Mode == (int)Samplers::Fuzz) lightshade = 256; - dest[ix] = ShadeAndBlend8(fgcolor, bgcolor, fgshade, lightshade, colormaps, srcalpha, destalpha); - posU += stepU; - posV += stepV; - lightpos += lightstep; - } - - blockPosY.W += gradientY.W; - blockPosY.U += gradientY.U; - blockPosY.V += gradientY.V; - - dest += pitch; - } - } - else - { - // mask0 loop: - for (int y = 0; y < 4; y++) - { - float rcpW = 0x01000000 / blockPosY.W; - int32_t posU = (int32_t)(blockPosY.U * rcpW); - int32_t posV = (int32_t)(blockPosY.V * rcpW); - - fixed_t lightpos = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask); - - ScreenTriangleStepVariables blockPosX = blockPosY; - blockPosX.W += gradientX.W; - blockPosX.U += gradientX.U; - blockPosX.V += gradientX.V; - - rcpW = 0x01000000 / blockPosX.W; - int32_t nextU = (int32_t)(blockPosX.U * rcpW); - int32_t nextV = (int32_t)(blockPosX.V * rcpW); - int32_t stepU = (nextU - posU) / 8; - int32_t stepV = (nextV - posV) / 8; - - fixed_t lightnext = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosX.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - fixed_t lightstep = (lightnext - lightpos) / 8; - lightstep = lightstep & lightmask; - - for (int x = 0; x < 8; x++) - { - if (mask0 & (1 << 31)) - { - int lightshade = lightpos >> 8; - uint8_t bgcolor = dest[x]; - if (SamplerT::Mode == (int)Samplers::FogBoundary) color = bgcolor; - uint8_t fgcolor = Sample8(posU, posV, texPixels, texWidth, texHeight, color, translation); - uint32_t fgshade = SampleShade8(posU, posV, texPixels, texWidth, texHeight, destX + x, destY + y); - if (SamplerT::Mode == (int)Samplers::Fuzz) lightshade = 256; - dest[x] = ShadeAndBlend8(fgcolor, bgcolor, fgshade, lightshade, colormaps, srcalpha, destalpha); - } - - posU += stepU; - posV += stepV; - lightpos += lightstep; - - mask0 <<= 1; - } - - blockPosY.W += gradientY.W; - blockPosY.U += gradientY.U; - blockPosY.V += gradientY.V; - - dest += pitch; - } - - // mask1 loop: - for (int y = 0; y < 4; y++) - { - float rcpW = 0x01000000 / blockPosY.W; - int32_t posU = (int32_t)(blockPosY.U * rcpW); - int32_t posV = (int32_t)(blockPosY.V * rcpW); - - fixed_t lightpos = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask); - - ScreenTriangleStepVariables blockPosX = blockPosY; - blockPosX.W += gradientX.W; - blockPosX.U += gradientX.U; - blockPosX.V += gradientX.V; - - rcpW = 0x01000000 / blockPosX.W; - int32_t nextU = (int32_t)(blockPosX.U * rcpW); - int32_t nextV = (int32_t)(blockPosX.V * rcpW); - int32_t stepU = (nextU - posU) / 8; - int32_t stepV = (nextV - posV) / 8; - - fixed_t lightnext = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosX.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - fixed_t lightstep = (lightnext - lightpos) / 8; - lightstep = lightstep & lightmask; - - for (int x = 0; x < 8; x++) - { - if (mask1 & (1 << 31)) - { - int lightshade = lightpos >> 8; - uint8_t bgcolor = dest[x]; - if (SamplerT::Mode == (int)Samplers::FogBoundary) color = bgcolor; - uint8_t fgcolor = Sample8(posU, posV, texPixels, texWidth, texHeight, color, translation); - uint32_t fgshade = SampleShade8(posU, posV, texPixels, texWidth, texHeight, destX + x, destY + 4 + y); - if (SamplerT::Mode == (int)Samplers::Fuzz) lightshade = 256; - dest[x] = ShadeAndBlend8(fgcolor, bgcolor, fgshade, lightshade, colormaps, srcalpha, destalpha); - } - - posU += stepU; - posV += stepV; - lightpos += lightstep; - - mask1 <<= 1; - } - - blockPosY.W += gradientY.W; - blockPosY.U += gradientY.U; - blockPosY.V += gradientY.V; - - dest += pitch; - } - } - } -}; - template class RectScreenDrawer8 { diff --git a/src/polyrenderer/drawers/poly_triangle.cpp b/src/polyrenderer/drawers/poly_triangle.cpp index beefb33d7..5661f5c83 100644 --- a/src/polyrenderer/drawers/poly_triangle.cpp +++ b/src/polyrenderer/drawers/poly_triangle.cpp @@ -39,12 +39,19 @@ #include "screen_triangle.h" #include "x86.h" +static bool isBgraRenderTarget = false; + void PolyTriangleDrawer::ClearBuffers(DCanvas *canvas) { PolyStencilBuffer::Instance()->Clear(canvas->GetWidth(), canvas->GetHeight(), 0); PolyZBuffer::Instance()->Resize(canvas->GetPitch(), canvas->GetHeight()); } +bool PolyTriangleDrawer::IsBgra() +{ + return isBgraRenderTarget; +} + void PolyTriangleDrawer::SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas, bool span_drawers) { uint8_t *dest = (uint8_t*)canvas->GetPixels(); @@ -52,6 +59,7 @@ void PolyTriangleDrawer::SetViewport(const DrawerCommandQueuePtr &queue, int x, int dest_height = canvas->GetHeight(); int dest_pitch = canvas->GetPitch(); bool dest_bgra = canvas->IsBgra(); + isBgraRenderTarget = dest_bgra; int offsetx = clamp(x, 0, dest_width); int offsety = clamp(y, 0, dest_height); diff --git a/src/polyrenderer/drawers/poly_triangle.h b/src/polyrenderer/drawers/poly_triangle.h index 628bdb009..b10888455 100644 --- a/src/polyrenderer/drawers/poly_triangle.h +++ b/src/polyrenderer/drawers/poly_triangle.h @@ -38,6 +38,8 @@ public: static void SetTwoSided(const DrawerCommandQueuePtr &queue, bool twosided); static void SetWeaponScene(const DrawerCommandQueuePtr &queue, bool enable); static void SetTransform(const DrawerCommandQueuePtr &queue, const Mat4f *objectToClip); + + static bool IsBgra(); }; class PolyTriangleThreadData diff --git a/src/polyrenderer/drawers/screen_triangle.cpp b/src/polyrenderer/drawers/screen_triangle.cpp index 1ee1aa947..a8a4fcd54 100644 --- a/src/polyrenderer/drawers/screen_triangle.cpp +++ b/src/polyrenderer/drawers/screen_triangle.cpp @@ -307,7 +307,7 @@ void TriangleBlock::RenderBlock(int x0, int y0, int x1, int y1) bool writeDepth = args->uniforms->WriteDepth(); int bmode = (int)args->uniforms->BlendMode(); - auto drawFunc = args->destBgra ? ScreenTriangle::TriDrawers32[bmode] : ScreenTriangle::TriDrawers8[bmode]; + auto drawFunc = args->destBgra ? ScreenTriangle::SpanDrawers32[bmode] : ScreenTriangle::SpanDrawers8[bmode]; // Loop through blocks for (int y = start_miny; y < y1; y += q * num_cores) @@ -345,7 +345,66 @@ void TriangleBlock::RenderBlock(int x0, int y0, int x1, int y1) } if (writeColor) - drawFunc(X, Y, Mask0, Mask1, args); + { + if (Mask0 == 0xffffffff) + { + drawFunc(Y, X, X + 8, args); + drawFunc(Y + 1, X, X + 8, args); + drawFunc(Y + 2, X, X + 8, args); + drawFunc(Y + 3, X, X + 8, args); + } + else if (Mask0 != 0) + { + uint32_t mask = Mask0; + for (int j = 0; j < 4; j++) + { + int start = 0; + int i; + for (i = 0; i < 8; i++) + { + if (!(mask & 0x80000000)) + { + if (i > start) + drawFunc(Y + j, X + start, X + i, args); + start = i + 1; + } + mask <<= 1; + } + if (i > start) + drawFunc(Y + j, X + start, X + i, args); + } + } + + if (Mask1 == 0xffffffff) + { + drawFunc(Y + 4, X, X + 8, args); + drawFunc(Y + 5, X, X + 8, args); + drawFunc(Y + 6, X, X + 8, args); + drawFunc(Y + 7, X, X + 8, args); + } + else if (Mask1 != 0) + { + uint32_t mask = Mask1; + for (int j = 4; j < 8; j++) + { + int start = 0; + int i; + for (i = 0; i < 8; i++) + { + if (!(mask & 0x80000000)) + { + if (i > start) + drawFunc(Y + j, X + start, X + i, args); + start = i + 1; + } + mask <<= 1; + } + if (i > start) + drawFunc(Y + j, X + start, X + i, args); + } + } + } + if (writeStencil) StencilWrite(); if (writeDepth) @@ -1249,210 +1308,102 @@ void ScreenTriangle::DrawSWRender(const TriDrawTriangleArgs *args, PolyTriangleT } } -template -void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args) +template +void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) { using namespace TriScreenDrawerModes; - float v1X = args->v1->x; - float v1Y = args->v1->y; - float v1W = args->v1->w; - float v1U = args->v1->u * v1W; - float v1V = args->v1->v * v1W; - float stepXW = args->gradientX.W; - float stepXU = args->gradientX.U; - float stepXV = args->gradientX.V; - float startX = x0 + (0.5f - v1X); - float startY = y + (0.5f - v1Y); - float posXW = v1W + stepXW * startX + args->gradientY.W * startY; - float posXU = v1U + stepXU * startX + args->gradientY.U * startY; - float posXV = v1V + stepXV * startX + args->gradientY.V * startY; + float v1X, v1Y, v1W, v1U, v1V, v1WorldX, v1WorldY, v1WorldZ; + float startX, startY; + float stepXW, stepXU, stepXV, stepWorldX, stepWorldY, stepWorldZ; + float posXW, posXU, posXV, posWorldX, posWorldY, posWorldZ; - const uint32_t *texPixels = (const uint32_t*)args->uniforms->TexturePixels(); - const uint32_t *translation = (const uint32_t*)args->uniforms->Translation(); - int texWidth = args->uniforms->TextureWidth(); - int texHeight = args->uniforms->TextureHeight(); + PolyLight *lights; + int num_lights; + float worldnormalX, worldnormalY, worldnormalZ; + uint32_t dynlightcolor; + const uint32_t *texPixels, *translation; + int texWidth, texHeight; + uint32_t fillcolor; + int alpha; + uint32_t light; + fixed_t shade, lightpos, lightstep; + uint32_t shade_fade_r, shade_fade_g, shade_fade_b, shade_light_r, shade_light_g, shade_light_b, desaturate, inv_desaturate; - int fillcolor = args->uniforms->Color(); - int alpha = args->uniforms->SrcAlpha(); + v1X = args->v1->x; + v1Y = args->v1->y; + v1W = args->v1->w; + v1U = args->v1->u * v1W; + v1V = args->v1->v * v1W; + startX = x0 + (0.5f - v1X); + startY = y + (0.5f - v1Y); + stepXW = args->gradientX.W; + stepXU = args->gradientX.U; + stepXV = args->gradientX.V; + posXW = v1W + stepXW * startX + args->gradientY.W * startY; + posXU = v1U + stepXU * startX + args->gradientY.U * startY; + posXV = v1V + stepXV * startX + args->gradientY.V * startY; - bool is_fixed_light = args->uniforms->FixedLight(); - uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff; - 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 + texPixels = (const uint32_t*)args->uniforms->TexturePixels(); + translation = (const uint32_t*)args->uniforms->Translation(); + texWidth = args->uniforms->TextureWidth(); + texHeight = args->uniforms->TextureHeight(); + fillcolor = args->uniforms->Color(); + alpha = args->uniforms->Alpha(); + light = args->uniforms->Light(); + + if (OptT::Flags & SWOPT_FixedLight) + { + light += light >> 7; // 255 -> 256 + } + else + { + float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f); + + shade = (fixed_t)((2.0f - (light + 12.0f) / 128.0f) * (float)FRACUNIT); + lightpos = (fixed_t)(globVis * posXW * (float)FRACUNIT); + lightstep = (fixed_t)(globVis * stepXW * (float)FRACUNIT); + } + + if (OptT::Flags & SWOPT_DynLights) + { + v1WorldX = args->v1->worldX * v1W; + v1WorldY = args->v1->worldY * v1W; + v1WorldZ = args->v1->worldZ * v1W; + stepWorldX = args->gradientX.WorldX; + stepWorldY = args->gradientX.WorldY; + stepWorldZ = args->gradientX.WorldZ; + posWorldX = v1WorldX + stepWorldX * startX + args->gradientY.WorldX * startY; + posWorldY = v1WorldY + stepWorldY * startX + args->gradientY.WorldY * startY; + posWorldZ = v1WorldZ + stepWorldZ * startX + args->gradientY.WorldZ * startY; + + lights = args->uniforms->Lights(); + num_lights = args->uniforms->NumLights(); + worldnormalX = args->uniforms->Normal().X; + worldnormalY = args->uniforms->Normal().Y; + worldnormalZ = args->uniforms->Normal().Z; + dynlightcolor = args->uniforms->DynLightColor(); + } + + if (OptT::Flags & SWOPT_ColoredFog) + { + shade_fade_r = args->uniforms->ShadeFadeRed(); + shade_fade_g = args->uniforms->ShadeFadeGreen(); + shade_fade_b = args->uniforms->ShadeFadeBlue(); + shade_light_r = args->uniforms->ShadeLightRed(); + shade_light_g = args->uniforms->ShadeLightGreen(); + shade_light_b = args->uniforms->ShadeLightBlue(); + desaturate = args->uniforms->ShadeDesaturate(); + inv_desaturate = 256 - desaturate; + } uint32_t *dest = (uint32_t*)args->dest; uint32_t *destLine = dest + args->pitch * y; int x = x0; - -#ifndef NO_SSE - __m128i mfillcolor = _mm_set1_epi32(fillcolor); - __m128i mcapcolor = _mm_unpacklo_epi8(mfillcolor, _mm_setzero_si128()); - __m128i malpha = _mm_set1_epi32(alpha); - - int sseEnd = x0 + ((x1 - x0) & ~3); - while (x < sseEnd) - { - __m128i fg; - - if (ModeT::SWFlags & SWSTYLEF_Fill) - { - fg = mfillcolor; - } - else if (ModeT::SWFlags & SWSTYLEF_FogBoundary) - { - fg = _mm_loadl_epi64((const __m128i*)(destLine + x)); - } - else - { - float rcpW0 = 0x01000000 / posXW; - float rcpW1 = 0x01000000 / (posXW + stepXW); - - int32_t u0 = (int32_t)(posXU * rcpW0); - int32_t u1 = (int32_t)((posXU + stepXU) * rcpW1); - int32_t v0 = (int32_t)(posXV * rcpW0); - int32_t v1 = (int32_t)((posXV + stepXV) * rcpW1); - uint32_t texelX0 = ((((uint32_t)u0 << 8) >> 16) * texWidth) >> 16; - uint32_t texelX1 = ((((uint32_t)u1 << 8) >> 16) * texWidth) >> 16; - uint32_t texelY0 = ((((uint32_t)v0 << 8) >> 16) * texHeight) >> 16; - uint32_t texelY1 = ((((uint32_t)v1 << 8) >> 16) * texHeight) >> 16; - - if (ModeT::SWFlags & SWSTYLEF_Translated) - { - uint32_t fg0 = translation[((const uint8_t*)texPixels)[texelX0 * texHeight + texelY0]]; - uint32_t fg1 = translation[((const uint8_t*)texPixels)[texelX1 * texHeight + texelY1]]; - fg = _mm_setr_epi32(fg0, fg1, 0, 0); - } - else - { - uint32_t fg0 = texPixels[texelX0 * texHeight + texelY0]; - uint32_t fg1 = texPixels[texelX1 * texHeight + texelY1]; - fg = _mm_setr_epi32(fg0, fg1, 0, 0); - } - } - - if (ModeT::SWFlags & SWSTYLEF_Skycap) - { - float rcpW0 = 0x01000000 / posXW; - float rcpW1 = 0x01000000 / (posXW + stepXW); - int32_t v0 = (int32_t)(posXV * rcpW0); - int32_t v1 = (int32_t)((posXV + stepXV) * rcpW1); - - int start_fade = 2; // How fast it should fade out - __m128i v = _mm_setr_epi32(v0, v0, v1, v1); - __m128i alpha_top = _mm_min_epi16(_mm_max_epi16(_mm_srai_epi32(v, 16 - start_fade), _mm_setzero_si128()), _mm_set1_epi16(256)); - __m128i alpha_bottom = _mm_min_epi16(_mm_max_epi16(_mm_srai_epi32(_mm_sub_epi32(_mm_set1_epi32(2 << 24), v), 16 - start_fade), _mm_setzero_si128()), _mm_set1_epi16(256)); - __m128i a = _mm_min_epi16(alpha_top, alpha_bottom); - a = _mm_shufflelo_epi16(_mm_shufflehi_epi16(a, _MM_SHUFFLE(0, 0, 0, 0)), _MM_SHUFFLE(0, 0, 0, 0)); - __m128i inv_a = _mm_sub_epi32(_mm_set1_epi32(256), a); - - fg = _mm_unpacklo_epi8(fg, _mm_setzero_si128()); - __m128i c = _mm_srli_epi16(_mm_add_epi16(_mm_add_epi16(_mm_mullo_epi16(fg, a), _mm_mullo_epi16(mcapcolor, inv_a)), _mm_set1_epi16(127)), 8); - _mm_storel_epi64((__m128i*)(destLine + x), _mm_packus_epi16(c, c)); - } - else - { - if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill)) - { - __m128i rgbmask = _mm_set1_epi32(0x00ffffff); - if (ModeT::Flags & STYLEF_RedIsAlpha) - fg = _mm_or_si128(_mm_andnot_si128(rgbmask, _mm_slli_epi32(fg, 8)), _mm_and_si128(rgbmask, mfillcolor)); - else - fg = _mm_or_si128(_mm_andnot_si128(rgbmask, fg), _mm_and_si128(rgbmask, mfillcolor)); - } - - if (!(ModeT::Flags & STYLEF_Alpha1)) - { - __m128i a = _mm_srli_epi32(fg, 24); - a = _mm_srli_epi32(_mm_mullo_epi16(a, malpha), 8); - fg = _mm_or_si128(_mm_and_si128(fg, _mm_set1_epi32(0x00ffffff)), _mm_slli_epi32(a, 24)); - } - - fg = _mm_unpacklo_epi8(fg, _mm_setzero_si128()); - - fixed_t lightpos0 = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * posXW), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - fixed_t lightpos1 = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * (posXW + stepXW)), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - lightpos0 = (lightpos0 & lightmask) | ((light << 8) & ~lightmask); - lightpos1 = (lightpos1 & lightmask) | ((light << 8) & ~lightmask); - int lightshade0 = lightpos0 >> 8; - int lightshade1 = lightpos1 >> 8; - __m128i shadedfg = _mm_srli_epi16(_mm_mullo_epi16(fg, _mm_setr_epi16(lightshade0, lightshade0, lightshade0, 256, lightshade1, lightshade1, lightshade1, 256)), 8); - - __m128i out; - if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_Zero) - { - out = shadedfg; - } - else if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_One) - { - __m128i dest = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(destLine + x)), _mm_setzero_si128()); - if (ModeT::BlendOp == STYLEOP_Add) - { - out = _mm_add_epi16(dest, shadedfg); - } - else if (ModeT::BlendOp == STYLEOP_RevSub) - { - out = _mm_sub_epi16(dest, shadedfg); - } - else //if (ModeT::BlendOp == STYLEOP_Sub) - { - out = _mm_sub_epi16(shadedfg, dest); - } - } - else if (ModeT::SWFlags & SWSTYLEF_SrcColorOneMinusSrcColor) - { - __m128i dest = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(destLine + x)), _mm_setzero_si128()); - __m128i sfactor = _mm_add_epi16(shadedfg, _mm_srli_epi16(shadedfg, 7)); - __m128i dfactor = _mm_sub_epi16(_mm_set1_epi16(256), sfactor); - out = _mm_srli_epi16(_mm_add_epi16(_mm_add_epi16(_mm_mullo_epi16(dest, dfactor), _mm_mullo_epi16(shadedfg, sfactor)), _mm_set1_epi16(127)), 8); - } - else - { - __m128i dest = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(destLine + x)), _mm_setzero_si128()); - - __m128i sfactor = _mm_shufflehi_epi16(_mm_shufflelo_epi16(shadedfg, _MM_SHUFFLE(3, 3, 3, 3)), _MM_SHUFFLE(3, 3, 3, 3)); - sfactor = _mm_add_epi16(sfactor, _mm_srli_epi16(sfactor, 7)); // 255 -> 256 - __m128i dfactor = _mm_sub_epi16(_mm_set1_epi16(256), sfactor); - __m128i src = _mm_mullo_epi16(shadedfg, sfactor); - if (ModeT::BlendDest == STYLEALPHA_One) - { - dest = _mm_slli_epi16(dest, 8); - } - else - { - __m128i dfactor = _mm_sub_epi16(_mm_set1_epi16(256), sfactor); - dest = _mm_mullo_epi16(dest, dfactor); - } - - if (ModeT::BlendOp == STYLEOP_Add) - { - out = _mm_srli_epi16(_mm_add_epi16(_mm_add_epi16(dest, src), _mm_set1_epi16(127)), 8); - } - else if (ModeT::BlendOp == STYLEOP_RevSub) - { - out = _mm_srli_epi16(_mm_add_epi16(_mm_sub_epi16(dest, src), _mm_set1_epi16(127)), 8); - } - else //if (ModeT::BlendOp == STYLEOP_Sub) - { - out = _mm_srli_epi16(_mm_add_epi16(_mm_sub_epi16(src, dest), _mm_set1_epi16(127)), 8); - } - } - _mm_storel_epi64((__m128i*)(destLine + x), _mm_or_si128(_mm_packus_epi16(out, out), _mm_set1_epi32(0xff000000))); - } - - posXW += stepXW + stepXW; - posXU += stepXU + stepXU; - posXV += stepXV + stepXV; - x += 2; - } -#endif - while (x < x1) { - uint32_t fg; + uint32_t fg = 0; if (ModeT::SWFlags & SWSTYLEF_Fill) { @@ -1462,7 +1413,7 @@ void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args) { fg = destLine[x]; } - else + else if (ModeT::BlendOp != STYLEOP_Fuzz) { float rcpW = 0x01000000 / posXW; int32_t u = (int32_t)(posXU * rcpW); @@ -1474,13 +1425,48 @@ void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args) { fg = translation[((const uint8_t*)texPixels)[texelX * texHeight + texelY]]; } + else if (ModeT::Flags & STYLEF_RedIsAlpha) + { + fg = ((const uint8_t*)texPixels)[texelX * texHeight + texelY]; + } else { fg = texPixels[texelX * texHeight + texelY]; } } - if (ModeT::SWFlags & SWSTYLEF_Skycap) + if (ModeT::BlendOp == STYLEOP_Fuzz) + { + using namespace swrenderer; + + float rcpW = 0x01000000 / posXW; + int32_t u = (int32_t)(posXU * rcpW); + int32_t v = (int32_t)(posXV * rcpW); + uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; + uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; + unsigned int sampleshadeout = APART(texPixels[texelX * texHeight + texelY]); + sampleshadeout += sampleshadeout >> 7; // 255 -> 256 + + fixed_t fuzzscale = (200 << FRACBITS) / viewheight; + + int scaled_x = (x * fuzzscale) >> FRACBITS; + int fuzz_x = fuzz_random_x_offset[scaled_x % FUZZ_RANDOM_X_SIZE] + fuzzpos; + + fixed_t fuzzcount = FUZZTABLE << FRACBITS; + fixed_t fuzz = ((fuzz_x << FRACBITS) + y * fuzzscale) % fuzzcount; + unsigned int alpha = fuzzoffset[fuzz >> FRACBITS]; + + sampleshadeout = (sampleshadeout * alpha) >> 5; + + uint32_t a = 256 - sampleshadeout; + + uint32_t dest = destLine[x]; + uint32_t out_r = (RPART(dest) * a) >> 8; + uint32_t out_g = (GPART(dest) * a) >> 8; + uint32_t out_b = (BPART(dest) * a) >> 8; + destLine[x] = MAKEARGB(255, out_r, out_g, out_b); + } + else if (ModeT::SWFlags & SWSTYLEF_Skycap) { float rcpW = 0x01000000 / posXW; int32_t v = (int32_t)(posXV * rcpW); @@ -1516,7 +1502,7 @@ void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args) if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill)) { if (ModeT::Flags & STYLEF_RedIsAlpha) - fg = ((fg << 8) & 0xff000000) | (fillcolor & 0x00ffffff); + fg = (fg << 24) | (fillcolor & 0x00ffffff); else fg = (fg & 0xff000000) | (fillcolor & 0x00ffffff); } @@ -1528,12 +1514,105 @@ void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args) fgalpha = (fgalpha * alpha) >> 8; } - fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * posXW), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask); - int lightshade = lightpos >> 8; - uint32_t shadedfg_r = (RPART(fg) * lightshade) >> 8; - uint32_t shadedfg_g = (GPART(fg) * lightshade) >> 8; - uint32_t shadedfg_b = (BPART(fg) * lightshade) >> 8; + int lightshade; + if (OptT::Flags & SWOPT_FixedLight) + { + lightshade = light; + } + else + { + fixed_t maxvis = 24 * FRACUNIT / 32; + fixed_t maxlight = 31 * FRACUNIT / 32; + lightshade = (FRACUNIT - clamp(shade - MIN(maxvis, lightpos), 0, maxlight)) >> 8; + } + + uint32_t lit_r = 0, lit_g = 0, lit_b = 0; + if (OptT::Flags & SWOPT_DynLights) + { + lit_r = RPART(dynlightcolor); + lit_g = GPART(dynlightcolor); + lit_b = BPART(dynlightcolor); + + float rcp_posXW = 1.0f / posXW; + float worldposX = posWorldX * rcp_posXW; + float worldposY = posWorldY * rcp_posXW; + float worldposZ = posWorldZ * rcp_posXW; + for (int i = 0; i < num_lights; i++) + { + float lightposX = lights[i].x; + float lightposY = lights[i].y; + float lightposZ = lights[i].z; + float light_radius = lights[i].radius; + uint32_t light_color = lights[i].color; + + bool is_attenuated = light_radius < 0.0f; + if (is_attenuated) + light_radius = -light_radius; + + // L = light-pos + // dist = sqrt(dot(L, L)) + // distance_attenuation = 1 - MIN(dist * (1/radius), 1) + float Lx = lightposX - worldposX; + float Ly = lightposY - worldposY; + float Lz = lightposZ - worldposZ; + float dist2 = Lx * Lx + Ly * Ly + Lz * Lz; +#ifdef NO_SSE + //float rcp_dist = 1.0f / sqrt(dist2); + float rcp_dist = 1.0f / (dist2 * 0.01f); +#else + float rcp_dist = _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(dist2))); +#endif + float dist = dist2 * rcp_dist; + float distance_attenuation = 256.0f - MIN(dist * light_radius, 256.0f); + + // The simple light type + float simple_attenuation = distance_attenuation; + + // The point light type + // diffuse = max(dot(N,normalize(L)),0) * attenuation + Lx *= rcp_dist; + Ly *= rcp_dist; + Lz *= rcp_dist; + float dotNL = worldnormalX * Lx + worldnormalY * Ly + worldnormalZ * Lz; + float point_attenuation = MAX(dotNL, 0.0f) * distance_attenuation; + + uint32_t attenuation = (uint32_t)(is_attenuated ? (int32_t)point_attenuation : (int32_t)simple_attenuation); + + lit_r += (RPART(light_color) * attenuation) >> 8; + lit_g += (GPART(light_color) * attenuation) >> 8; + lit_b += (BPART(light_color) * attenuation) >> 8; + } + } + + uint32_t shadedfg_r, shadedfg_g, shadedfg_b; + if (OptT::Flags & SWOPT_ColoredFog) + { + uint32_t fg_r = RPART(fg); + uint32_t fg_g = GPART(fg); + uint32_t fg_b = BPART(fg); + uint32_t intensity = ((fg_r * 77 + fg_g * 143 + fg_b * 37) >> 8) * desaturate; + shadedfg_r = (((shade_fade_r + ((fg_r * inv_desaturate + intensity) >> 8) * lightshade) >> 8) * shade_light_r) >> 8; + shadedfg_g = (((shade_fade_g + ((fg_g * inv_desaturate + intensity) >> 8) * lightshade) >> 8) * shade_light_g) >> 8; + shadedfg_b = (((shade_fade_b + ((fg_b * inv_desaturate + intensity) >> 8) * lightshade) >> 8) * shade_light_b) >> 8; + + lit_r = MIN(lit_r, (uint32_t)256); + lit_g = MIN(lit_g, (uint32_t)256); + lit_b = MIN(lit_b, (uint32_t)256); + + shadedfg_r = MIN(shadedfg_r + ((fg_r * lit_r) >> 8), (uint32_t)255); + shadedfg_g = MIN(shadedfg_g + ((fg_g * lit_g) >> 8), (uint32_t)255); + shadedfg_b = MIN(shadedfg_b + ((fg_b * lit_b) >> 8), (uint32_t)255); + } + else + { + lit_r = MIN(lightshade + lit_r, (uint32_t)256); + lit_g = MIN(lightshade + lit_g, (uint32_t)256); + lit_b = MIN(lightshade + lit_b, (uint32_t)256); + + shadedfg_r = (RPART(fg) * lit_r) >> 8; + shadedfg_g = (GPART(fg) * lit_g) >> 8; + shadedfg_b = (BPART(fg) * lit_b) >> 8; + } if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_Zero) { @@ -1582,16 +1661,15 @@ void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args) destLine[x] = MAKEARGB(255, out_r, out_g, out_b); } - else if (fgalpha == 255) + else if (ModeT::BlendSrc == STYLEALPHA_Src && ModeT::BlendDest == STYLEALPHA_InvSrc && fgalpha == 255) { destLine[x] = MAKEARGB(255, shadedfg_r, shadedfg_g, shadedfg_b); } - else if (fgalpha != 0) + else if (ModeT::BlendSrc != STYLEALPHA_Src || ModeT::BlendDest != STYLEALPHA_InvSrc || fgalpha != 0) { uint32_t dest = destLine[x]; uint32_t sfactor = fgalpha; sfactor += sfactor >> 7; // 255 -> 256 - uint32_t dfactor = 256 - sfactor; uint32_t src_r = shadedfg_r * sfactor; uint32_t src_g = shadedfg_g * sfactor; uint32_t src_b = shadedfg_b * sfactor; @@ -1648,49 +1726,139 @@ void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args) posXW += stepXW; posXU += stepXU; posXV += stepXV; + if (OptT::Flags & SWOPT_DynLights) + { + posWorldX += stepWorldX; + posWorldY += stepWorldY; + posWorldZ += stepWorldZ; + } + if (!(OptT::Flags & SWOPT_FixedLight)) + lightpos += lightstep; x++; } } template -void DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs *args) +void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args) { using namespace TriScreenDrawerModes; - float v1X = args->v1->x; - float v1Y = args->v1->y; - float v1W = args->v1->w; - float v1U = args->v1->u * v1W; - float v1V = args->v1->v * v1W; - float stepXW = args->gradientX.W; - float stepXU = args->gradientX.U; - float stepXV = args->gradientX.V; - float startX = x0 + (0.5f - v1X); - float startY = y + (0.5f - v1Y); - float posXW = v1W + stepXW * startX + args->gradientY.W * startY; - float posXU = v1U + stepXU * startX + args->gradientY.U * startY; - float posXV = v1V + stepXV * startX + args->gradientY.V * startY; + if (args->uniforms->NumLights() == 0) + { + if (!args->uniforms->FixedLight()) + { + if (args->uniforms->SimpleShade()) + DrawSpanOpt32(y, x0, x1, args); + else + DrawSpanOpt32(y, x0, x1, args); + } + else + { + if (args->uniforms->SimpleShade()) + DrawSpanOpt32(y, x0, x1, args); + else + DrawSpanOpt32(y, x0, x1, args); + } + } + else + { + if (!args->uniforms->FixedLight()) + { + if (args->uniforms->SimpleShade()) + DrawSpanOpt32(y, x0, x1, args); + else + DrawSpanOpt32(y, x0, x1, args); + } + else + { + if (args->uniforms->SimpleShade()) + DrawSpanOpt32(y, x0, x1, args); + else + DrawSpanOpt32(y, x0, x1, args); + } + } +} - auto colormaps = args->uniforms->BaseColormap(); +template +void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args) +{ + using namespace TriScreenDrawerModes; - const uint8_t *texPixels = args->uniforms->TexturePixels(); - const uint8_t *translation = args->uniforms->Translation(); - int texWidth = args->uniforms->TextureWidth(); - int texHeight = args->uniforms->TextureHeight(); + float v1X, v1Y, v1W, v1U, v1V, v1WorldX, v1WorldY, v1WorldZ; + float startX, startY; + float stepXW, stepXU, stepXV, stepWorldX, stepWorldY, stepWorldZ; + float posXW, posXU, posXV, posWorldX, posWorldY, posWorldZ; - int fillcolor = args->uniforms->Color(); - int alpha = args->uniforms->SrcAlpha(); + PolyLight *lights; + int num_lights; + float worldnormalX, worldnormalY, worldnormalZ; + uint32_t dynlightcolor; + const uint8_t *colormaps, *texPixels, *translation; + int texWidth, texHeight; + uint32_t fillcolor, capcolor; + int alpha; + uint32_t light; + fixed_t shade, lightpos, lightstep; + + v1X = args->v1->x; + v1Y = args->v1->y; + v1W = args->v1->w; + v1U = args->v1->u * v1W; + v1V = args->v1->v * v1W; + startX = x0 + (0.5f - v1X); + startY = y + (0.5f - v1Y); + stepXW = args->gradientX.W; + stepXU = args->gradientX.U; + stepXV = args->gradientX.V; + posXW = v1W + stepXW * startX + args->gradientY.W * startY; + posXU = v1U + stepXU * startX + args->gradientY.U * startY; + posXV = v1V + stepXV * startX + args->gradientY.V * startY; + + texPixels = args->uniforms->TexturePixels(); + translation = args->uniforms->Translation(); + texWidth = args->uniforms->TextureWidth(); + texHeight = args->uniforms->TextureHeight(); + fillcolor = args->uniforms->Color(); + alpha = args->uniforms->Alpha(); + colormaps = args->uniforms->BaseColormap(); + light = args->uniforms->Light(); - uint32_t capcolor = fillcolor; if (ModeT::SWFlags & SWSTYLEF_Skycap) - capcolor = GPalette.BaseColors[capcolor].d; + capcolor = GPalette.BaseColors[fillcolor].d; - bool is_fixed_light = args->uniforms->FixedLight(); - uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff; - 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 + if (OptT::Flags & SWOPT_FixedLight) + { + light += light >> 7; // 255 -> 256 + light = ((256 - light) * NUMCOLORMAPS) & 0xffffff00; + } + else + { + float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f); + + shade = (fixed_t)((2.0f - (light + 12.0f) / 128.0f) * (float)FRACUNIT); + lightpos = (fixed_t)(globVis * posXW * (float)FRACUNIT); + lightstep = (fixed_t)(globVis * stepXW * (float)FRACUNIT); + } + + if (OptT::Flags & SWOPT_DynLights) + { + v1WorldX = args->v1->worldX * v1W; + v1WorldY = args->v1->worldY * v1W; + v1WorldZ = args->v1->worldZ * v1W; + stepWorldX = args->gradientX.WorldX; + stepWorldY = args->gradientX.WorldY; + stepWorldZ = args->gradientX.WorldZ; + posWorldX = v1WorldX + stepWorldX * startX + args->gradientY.WorldX * startY; + posWorldY = v1WorldY + stepWorldY * startX + args->gradientY.WorldY * startY; + posWorldZ = v1WorldZ + stepWorldZ * startX + args->gradientY.WorldZ * startY; + + lights = args->uniforms->Lights(); + num_lights = args->uniforms->NumLights(); + worldnormalX = args->uniforms->Normal().X; + worldnormalY = args->uniforms->Normal().Y; + worldnormalZ = args->uniforms->Normal().Z; + dynlightcolor = args->uniforms->DynLightColor(); + } uint8_t *dest = (uint8_t*)args->dest; uint8_t *destLine = dest + args->pitch * y; @@ -1698,7 +1866,7 @@ void DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs *args) int x = x0; while (x < x1) { - int fg; + int fg = 0; int fgalpha = 255; if (ModeT::SWFlags & SWSTYLEF_Fill) @@ -1709,7 +1877,7 @@ void DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs *args) { fg = destLine[x]; } - else + else if (ModeT::BlendOp != STYLEOP_Fuzz) { float rcpW = 0x01000000 / posXW; int32_t u = (int32_t)(posXU * rcpW); @@ -1724,7 +1892,37 @@ void DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs *args) fgalpha = (fg != 0) ? 255 : 0; } - if (ModeT::SWFlags & SWSTYLEF_Skycap) + if (ModeT::BlendOp == STYLEOP_Fuzz) + { + using namespace swrenderer; + + float rcpW = 0x01000000 / posXW; + int32_t u = (int32_t)(posXU * rcpW); + int32_t v = (int32_t)(posXV * rcpW); + uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; + uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; + unsigned int sampleshadeout = (texPixels[texelX * texHeight + texelY] != 0) ? 256 : 0; + + fixed_t fuzzscale = (200 << FRACBITS) / viewheight; + + int scaled_x = (x * fuzzscale) >> FRACBITS; + int fuzz_x = fuzz_random_x_offset[scaled_x % FUZZ_RANDOM_X_SIZE] + fuzzpos; + + fixed_t fuzzcount = FUZZTABLE << FRACBITS; + fixed_t fuzz = ((fuzz_x << FRACBITS) + y * fuzzscale) % fuzzcount; + unsigned int alpha = fuzzoffset[fuzz >> FRACBITS]; + + sampleshadeout = (sampleshadeout * alpha) >> 5; + + uint32_t a = 256 - sampleshadeout; + + uint32_t dest = GPalette.BaseColors[destLine[x]].d; + uint32_t r = (RPART(dest) * a) >> 8; + uint32_t g = (GPART(dest) * a) >> 8; + uint32_t b = (BPART(dest) * a) >> 8; + destLine[x] = RGB256k.All[((r >> 2) << 12) | ((g >> 2) << 6) | (b >> 2)]; + } + else if (ModeT::SWFlags & SWSTYLEF_Skycap) { float rcpW = 0x01000000 / posXW; int32_t v = (int32_t)(posXV * rcpW); @@ -1771,11 +1969,95 @@ void DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs *args) fgalpha = (fgalpha * alpha) >> 8; } - fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * posXW), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask); - int lightshade = lightpos >> 8; - lightshade = ((256 - lightshade) * NUMCOLORMAPS) & 0xffffff00; - uint8_t shadedfg = colormaps[lightshade + fg]; + uint8_t shadedfg; + if (OptT::Flags & SWOPT_FixedLight) + { + shadedfg = colormaps[light + fg]; + } + else + { + fixed_t maxvis = 24 * FRACUNIT / 32; + fixed_t maxlight = 31 * FRACUNIT / 32; + int lightshade = (FRACUNIT - clamp(shade - MIN(maxvis, lightpos), 0, maxlight)) >> 8; + lightshade = ((256 - lightshade) << 5) & 0xffffff00; + shadedfg = colormaps[lightshade + fg]; + } + + if (OptT::Flags & SWOPT_DynLights) + { + uint32_t lit_r = RPART(dynlightcolor); + uint32_t lit_g = GPART(dynlightcolor); + uint32_t lit_b = BPART(dynlightcolor); + +#ifdef NO_SSE + float rcp_posXW = 1.0f / posXW; +#else + float rcp_posXW = _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ss(posXW))); +#endif + float worldposX = posWorldX * rcp_posXW; + float worldposY = posWorldY * rcp_posXW; + float worldposZ = posWorldZ * rcp_posXW; + for (int i = 0; i < num_lights; i++) + { + float lightposX = lights[i].x; + float lightposY = lights[i].y; + float lightposZ = lights[i].z; + float light_radius = lights[i].radius; + uint32_t light_color = lights[i].color; + + bool is_attenuated = light_radius < 0.0f; + if (is_attenuated) + light_radius = -light_radius; + + // L = light-pos + // dist = sqrt(dot(L, L)) + // distance_attenuation = 1 - MIN(dist * (1/radius), 1) + float Lx = lightposX - worldposX; + float Ly = lightposY - worldposY; + float Lz = lightposZ - worldposZ; + float dist2 = Lx * Lx + Ly * Ly + Lz * Lz; +#ifdef NO_SSE + //float rcp_dist = 1.0f / sqrt(dist2); + float rcp_dist = 1.0f / (dist2 * 0.01f); +#else + float rcp_dist = _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(dist2))); +#endif + float dist = dist2 * rcp_dist; + float distance_attenuation = 256.0f - MIN(dist * light_radius, 256.0f); + + // The simple light type + float simple_attenuation = distance_attenuation; + + // The point light type + // diffuse = max(dot(N,normalize(L)),0) * attenuation + Lx *= rcp_dist; + Ly *= rcp_dist; + Lz *= rcp_dist; + float dotNL = worldnormalX * Lx + worldnormalY * Ly + worldnormalZ * Lz; + float point_attenuation = MAX(dotNL, 0.0f) * distance_attenuation; + + uint32_t attenuation = (uint32_t)(is_attenuated ? (int32_t)point_attenuation : (int32_t)simple_attenuation); + + lit_r += (RPART(light_color) * attenuation) >> 8; + lit_g += (GPART(light_color) * attenuation) >> 8; + lit_b += (BPART(light_color) * attenuation) >> 8; + } + + if (lit_r || lit_g || lit_b) + { + lit_r = MIN(lit_r, (uint32_t)256); + lit_g = MIN(lit_g, (uint32_t)256); + lit_b = MIN(lit_b, (uint32_t)256); + + uint32_t fgrgb = GPalette.BaseColors[fg]; + uint32_t shadedfgrgb = GPalette.BaseColors[shadedfg]; + + uint32_t out_r = MIN(((RPART(fgrgb) * lit_r) >> 8) + RPART(shadedfgrgb), (uint32_t)255); + uint32_t out_g = MIN(((GPART(fgrgb) * lit_g) >> 8) + GPART(shadedfgrgb), (uint32_t)255); + uint32_t out_b = MIN(((BPART(fgrgb) * lit_b) >> 8) + BPART(shadedfgrgb), (uint32_t)255); + shadedfg = RGB256k.All[((out_r >> 2) << 12) | ((out_g >> 2) << 6) | (out_b >> 2)]; + } + } if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_Zero) { @@ -1826,11 +2108,11 @@ void DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs *args) destLine[x] = RGB256k.All[((out_r >> 2) << 12) | ((out_g >> 2) << 6) | (out_b >> 2)]; } - else if (fgalpha == 255) + else if (ModeT::BlendSrc == STYLEALPHA_Src && ModeT::BlendDest == STYLEALPHA_InvSrc && fgalpha == 255) { destLine[x] = shadedfg; } - else if (fgalpha != 0) + else if (ModeT::BlendSrc != STYLEALPHA_Src || ModeT::BlendDest != STYLEALPHA_InvSrc || fgalpha != 0) { uint32_t src = GPalette.BaseColors[shadedfg]; uint32_t dest = GPalette.BaseColors[destLine[x]]; @@ -1893,10 +2175,39 @@ void DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs *args) posXW += stepXW; posXU += stepXU; posXV += stepXV; + if (OptT::Flags & SWOPT_DynLights) + { + posWorldX += stepWorldX; + posWorldY += stepWorldY; + posWorldZ += stepWorldZ; + } + if (!(OptT::Flags & SWOPT_FixedLight)) + lightpos += lightstep; x++; } } +template +void DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs *args) +{ + using namespace TriScreenDrawerModes; + + if (args->uniforms->NumLights() == 0) + { + if (!args->uniforms->FixedLight()) + DrawSpanOpt8(y, x0, x1, args); + else + DrawSpanOpt8(y, x0, x1, args); + } + else + { + if (!args->uniforms->FixedLight()) + DrawSpanOpt8(y, x0, x1, args); + else + DrawSpanOpt8(y, x0, x1, args); + } +} + void(*ScreenTriangle::SpanDrawers8[])(int, int, int, const TriDrawTriangleArgs *) = { &DrawSpan8, @@ -1961,62 +2272,6 @@ void(*ScreenTriangle::SpanDrawers32[])(int, int, int, const TriDrawTriangleArgs &DrawSpan32 }; -void(*ScreenTriangle::TriDrawers8[])(int, int, uint32_t, uint32_t, const TriDrawTriangleArgs *) = -{ - &TriScreenDrawer8::Execute, // TextureOpaque - &TriScreenDrawer8::Execute, // TextureMasked - &TriScreenDrawer8::Execute, // TextureAdd - &TriScreenDrawer8::Execute, // TextureSub - &TriScreenDrawer8::Execute, // TextureRevSub - &TriScreenDrawer8::Execute, // TextureAddSrcColor - &TriScreenDrawer8::Execute, // TranslatedOpaque - &TriScreenDrawer8::Execute, // TranslatedMasked - &TriScreenDrawer8::Execute, // TranslatedAdd - &TriScreenDrawer8::Execute, // TranslatedSub - &TriScreenDrawer8::Execute, // TranslatedRevSub - &TriScreenDrawer8::Execute, // TranslatedAddSrcColor - &TriScreenDrawer8::Execute, // Shaded - &TriScreenDrawer8::Execute, // AddShaded - &TriScreenDrawer8::Execute, // Stencil - &TriScreenDrawer8::Execute, // AddStencil - &TriScreenDrawer8::Execute, // FillOpaque - &TriScreenDrawer8::Execute, // FillAdd - &TriScreenDrawer8::Execute, // FillSub - &TriScreenDrawer8::Execute, // FillRevSub - &TriScreenDrawer8::Execute, // FillAddSrcColor - &TriScreenDrawer8::Execute, // Skycap - &TriScreenDrawer8::Execute, // Fuzz - &TriScreenDrawer8::Execute, // FogBoundary -}; - -void(*ScreenTriangle::TriDrawers32[])(int, int, uint32_t, uint32_t, const TriDrawTriangleArgs *) = -{ - &TriScreenDrawer32::Execute, // TextureOpaque - &TriScreenDrawer32::Execute, // TextureMasked - &TriScreenDrawer32::Execute, // TextureAdd - &TriScreenDrawer32::Execute, // TextureSub - &TriScreenDrawer32::Execute, // TextureRevSub - &TriScreenDrawer32::Execute, // TextureAddSrcColor - &TriScreenDrawer32::Execute, // TranslatedOpaque - &TriScreenDrawer32::Execute, // TranslatedMasked - &TriScreenDrawer32::Execute, // TranslatedAdd - &TriScreenDrawer32::Execute, // TranslatedSub - &TriScreenDrawer32::Execute, // TranslatedRevSub - &TriScreenDrawer32::Execute, // TranslatedAddSrcColor - &TriScreenDrawer32::Execute, // Shaded - &TriScreenDrawer32::Execute, // AddShaded - &TriScreenDrawer32::Execute, // Stencil - &TriScreenDrawer32::Execute, // AddStencil - &TriScreenDrawer32::Execute, // FillOpaque - &TriScreenDrawer32::Execute, // FillAdd - &TriScreenDrawer32::Execute, // FillSub - &TriScreenDrawer32::Execute, // FillRevSub - &TriScreenDrawer32::Execute, // FillAddSrcColor - &TriScreenDrawer32::Execute, // Skycap - &TriScreenDrawer32::Execute, // Fuzz - &TriScreenDrawer32::Execute // FogBoundary -}; - void(*ScreenTriangle::RectDrawers8[])(const void *, int, int, int, const RectDrawArgs *, PolyTriangleThreadData *) = { &RectScreenDrawer8::Execute, // TextureOpaque diff --git a/src/polyrenderer/drawers/screen_triangle.h b/src/polyrenderer/drawers/screen_triangle.h index c8a23c707..036e4a55b 100644 --- a/src/polyrenderer/drawers/screen_triangle.h +++ b/src/polyrenderer/drawers/screen_triangle.h @@ -107,6 +107,38 @@ private: class RectDrawArgs; enum class TriBlendMode +{ + Opaque, + Skycap, + FogBoundary, + SrcColor, + Fill, + Normal, + Fuzzy, + Stencil, + Translucent, + Add, + Shaded, + TranslucentStencil, + Shadow, + Subtract, + AddStencil, + AddShaded, + OpaqueTranslated, + SrcColorTranslated, + NormalTranslated, + StencilTranslated, + TranslucentTranslated, + AddTranslated, + ShadedTranslated, + TranslucentStencilTranslated, + ShadowTranslated, + SubtractTranslated, + AddStencilTranslated, + AddShadedTranslated +}; + +enum class RectBlendMode { TextureOpaque, TextureMasked, @@ -142,8 +174,6 @@ public: static void(*SpanDrawers8[])(int y, int x0, int x1, const TriDrawTriangleArgs *args); static void(*SpanDrawers32[])(int y, int x0, int x1, const TriDrawTriangleArgs *args); - static void(*TriDrawers8[])(int, int, uint32_t, uint32_t, const TriDrawTriangleArgs *); - static void(*TriDrawers32[])(int, int, uint32_t, uint32_t, const TriDrawTriangleArgs *); static void(*RectDrawers8[])(const void *, int, int, int, const RectDrawArgs *, PolyTriangleThreadData *); static void(*RectDrawers32[])(const void *, int, int, int, const RectDrawArgs *, PolyTriangleThreadData *); @@ -221,6 +251,22 @@ namespace TriScreenDrawerModes struct FuzzSampler { static const int Mode = (int)Samplers::Fuzz; }; struct FogBoundarySampler { static const int Mode = (int)Samplers::FogBoundary; }; + enum SWOptFlags + { + SWOPT_DynLights = 1, + SWOPT_ColoredFog = 2, + SWOPT_FixedLight = 4 + }; + + struct DrawerOpt { static const int Flags = 0; }; + struct DrawerOptF { static const int Flags = SWOPT_FixedLight; }; + struct DrawerOptC { static const int Flags = SWOPT_ColoredFog; }; + struct DrawerOptCF { static const int Flags = SWOPT_ColoredFog | SWOPT_FixedLight; }; + struct DrawerOptL { static const int Flags = SWOPT_DynLights; }; + struct DrawerOptLC { static const int Flags = SWOPT_DynLights | SWOPT_ColoredFog; }; + struct DrawerOptLF { static const int Flags = SWOPT_DynLights | SWOPT_FixedLight; }; + struct DrawerOptLCF { static const int Flags = SWOPT_DynLights | SWOPT_ColoredFog | SWOPT_FixedLight; }; + static const int fuzzcolormap[FUZZTABLE] = { 6, 11, 6, 11, 6, 6, 11, 6, 6, 11, diff --git a/src/polyrenderer/scene/poly_model.cpp b/src/polyrenderer/scene/poly_model.cpp index cc8a111ea..344749659 100644 --- a/src/polyrenderer/scene/poly_model.cpp +++ b/src/polyrenderer/scene/poly_model.cpp @@ -56,12 +56,16 @@ void PolyModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, co ModelActor = actor; const_cast(objectToWorldMatrix).copy(ObjectToWorld.Matrix); SetTransform(); - PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true); + + if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] || !!(smf->flags & MDL_DONTCULLBACKFACES)) + PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true); } void PolyModelRenderer::EndDrawModel(AActor *actor, FSpriteModelFrame *smf) { - PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false); + if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] || !!(smf->flags & MDL_DONTCULLBACKFACES)) + PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false); + ModelActor = nullptr; } @@ -100,14 +104,18 @@ void PolyModelRenderer::BeginDrawHUDModel(AActor *actor, const VSMatrix &objectT const_cast(objectToWorldMatrix).copy(ObjectToWorld.Matrix); SetTransform(); PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, true); - PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true); + + if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal]) + PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true); } void PolyModelRenderer::EndDrawHUDModel(AActor *actor) { ModelActor = nullptr; PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, false); - PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false); + + if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal]) + PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false); } void PolyModelRenderer::SetInterpolation(double interpolation) @@ -146,8 +154,7 @@ void PolyModelRenderer::DrawArrays(int start, int count) args.SetLight(GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], true), lightlevel, PolyRenderer::Instance()->Light.SpriteGlobVis(foggy), fullbrightSprite); args.SetStencilTestValue(StencilValue); args.SetClipPlane(0, PolyClipPlane()); - args.SetStyle(TriBlendMode::TextureOpaque); - args.SetTexture(SkinTexture, DefaultRenderStyle()); + args.SetStyle(ModelActor->RenderStyle, ModelActor->Alpha, ModelActor->fillcolor, ModelActor->Translation, SkinTexture, fullbrightSprite); args.SetDepthTest(true); args.SetWriteDepth(true); args.SetWriteStencil(false); @@ -169,8 +176,7 @@ void PolyModelRenderer::DrawElements(int numIndices, size_t offset) args.SetLight(GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], true), lightlevel, PolyRenderer::Instance()->Light.SpriteGlobVis(foggy), fullbrightSprite); args.SetStencilTestValue(StencilValue); args.SetClipPlane(0, PolyClipPlane()); - args.SetStyle(TriBlendMode::TextureOpaque); - args.SetTexture(SkinTexture, DefaultRenderStyle()); + args.SetStyle(ModelActor->RenderStyle, ModelActor->Alpha, ModelActor->fillcolor, ModelActor->Translation, SkinTexture, fullbrightSprite); args.SetDepthTest(true); args.SetWriteDepth(true); args.SetWriteStencil(false); diff --git a/src/polyrenderer/scene/poly_particle.cpp b/src/polyrenderer/scene/poly_particle.cpp index 763343eb2..da2a2bba2 100644 --- a/src/polyrenderer/scene/poly_particle.cpp +++ b/src/polyrenderer/scene/poly_particle.cpp @@ -81,7 +81,7 @@ void RenderPolyParticle::Render(PolyRenderThread *thread, particle_t *particle, args.SetLight(GetColorTable(sub->sector->Colormap), lightlevel, PolyRenderer::Instance()->Light.ParticleGlobVis(foggy), fullbrightSprite); args.SetDepthTest(true); args.SetColor(particle->color | 0xff000000, particle->color >> 24); - args.SetStyle(TriBlendMode::Shaded, particle->alpha, 1.0 - particle->alpha); + args.SetStyle(TriBlendMode::Shaded, particle->alpha); args.SetStencilTestValue(stencilValue); args.SetWriteStencil(false); args.SetWriteDepth(false); diff --git a/src/polyrenderer/scene/poly_plane.cpp b/src/polyrenderer/scene/poly_plane.cpp index 54a0ac894..f43e51a93 100644 --- a/src/polyrenderer/scene/poly_plane.cpp +++ b/src/polyrenderer/scene/poly_plane.cpp @@ -79,7 +79,7 @@ void RenderPolyPlane::RenderNormal(PolyRenderThread *thread, const PolyTransferH args.SetStencilTestValue(stencilValue); args.SetWriteStencil(true, stencilValue + 1); args.SetTexture(tex, DefaultRenderStyle()); - args.SetStyle(TriBlendMode::TextureOpaque); + args.SetStyle(TriBlendMode::Opaque); args.DrawArray(thread->DrawQueue, vertices, fakeflat.Subsector->numlines, PolyDrawMode::TriangleFan); } else @@ -546,13 +546,11 @@ void Render3DFloorPlane::Render(PolyRenderThread *thread) args.SetLight(GetColorTable(sub->sector->Colormap), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), false); if (!Masked) { - args.SetStyle(TriBlendMode::TextureOpaque); + args.SetStyle(TriBlendMode::Opaque); } else { - double srcalpha = MIN(Alpha, 1.0); - double destalpha = Additive ? 1.0 : 1.0 - srcalpha; - args.SetStyle(TriBlendMode::TextureAdd, srcalpha, destalpha); + args.SetStyle(Additive ? TriBlendMode::Add : TriBlendMode::Normal, MIN(Alpha, 1.0)); args.SetDepthTest(true); args.SetWriteDepth(true); } diff --git a/src/polyrenderer/scene/poly_scene.cpp b/src/polyrenderer/scene/poly_scene.cpp index a446eba4c..cb31e2590 100644 --- a/src/polyrenderer/scene/poly_scene.cpp +++ b/src/polyrenderer/scene/poly_scene.cpp @@ -346,7 +346,7 @@ void RenderPolyScene::RenderPortals() { bool foggy = false; args.SetLight(&NormalLight, 255, PolyRenderer::Instance()->Light.WallGlobVis(foggy), true); - args.SetStyle(TriBlendMode::FillOpaque); + args.SetStyle(TriBlendMode::Fill); args.SetColor(0, 0); } diff --git a/src/polyrenderer/scene/poly_sky.cpp b/src/polyrenderer/scene/poly_sky.cpp index eef7b0583..e8b3faadd 100644 --- a/src/polyrenderer/scene/poly_sky.cpp +++ b/src/polyrenderer/scene/poly_sky.cpp @@ -121,7 +121,7 @@ void PolySkyDome::RenderCapColorRow(PolyRenderThread *thread, PolyDrawArgs &args uint8_t palsolid = RGB32k.RGB[(RPART(solid) >> 3)][(GPART(solid) >> 3)][(BPART(solid) >> 3)]; args.SetColor(solid, palsolid); - args.SetStyle(TriBlendMode::FillOpaque); + args.SetStyle(TriBlendMode::Fill); args.DrawArray(thread->DrawQueue, &mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], PolyDrawMode::TriangleFan); } diff --git a/src/polyrenderer/scene/poly_wall.cpp b/src/polyrenderer/scene/poly_wall.cpp index 2fd7bed17..68bc662dc 100644 --- a/src/polyrenderer/scene/poly_wall.cpp +++ b/src/polyrenderer/scene/poly_wall.cpp @@ -349,14 +349,19 @@ void RenderPolyWall::Render(PolyRenderThread *thread) { args.SetStencilTestValue(StencilValue); args.SetWriteStencil(true, StencilValue + 1); - args.SetStyle(TriBlendMode::TextureOpaque); + args.SetStyle(TriBlendMode::Opaque); DrawStripes(thread, args, vertices); } else { - double srcalpha = MIN(Alpha, 1.0); - double destalpha = Additive ? 1.0 : 1.0 - srcalpha; - args.SetStyle(TriBlendMode::TextureAdd, srcalpha, destalpha); + double a = MIN(Alpha, 1.0); + if (Additive) + args.SetStyle(TriBlendMode::Add, a); + else if (a < 1.0) + args.SetStyle(TriBlendMode::Translucent, a); + else + args.SetStyle(TriBlendMode::Normal); + args.SetStencilTestValue(StencilValue + 1); args.SetDepthTest(true); args.SetWriteDepth(true); diff --git a/src/polyrenderer/scene/poly_wallsprite.cpp b/src/polyrenderer/scene/poly_wallsprite.cpp index cf4b3ae16..90024866e 100644 --- a/src/polyrenderer/scene/poly_wallsprite.cpp +++ b/src/polyrenderer/scene/poly_wallsprite.cpp @@ -107,6 +107,6 @@ void RenderPolyWallSprite::Render(PolyRenderThread *thread, AActor *thing, subse args.SetDepthTest(true); args.SetWriteDepth(false); args.SetWriteStencil(false); - args.SetStyle(TriBlendMode::TextureMasked); + args.SetStyle(TriBlendMode::Normal); args.DrawArray(thread->DrawQueue, vertices, 4, PolyDrawMode::TriangleFan); } diff --git a/src/serializer.cpp b/src/serializer.cpp index aa1c9a49e..58d5658d4 100644 --- a/src/serializer.cpp +++ b/src/serializer.cpp @@ -989,6 +989,11 @@ void FSerializer::ReadObjects(bool hubtravel) { DThinker::bSerialOverride = true; r->mDObjects.Resize(ArraySize()); + for (auto &p : r->mDObjects) + { + p = nullptr; + } + // First iteration: create all the objects but do nothing with them yet. for (unsigned i = 0; i < r->mDObjects.Size(); i++) { @@ -1060,7 +1065,7 @@ void FSerializer::ReadObjects(bool hubtravel) // nuke all objects we created here. for (auto obj : r->mDObjects) { - if (!(obj->ObjectFlags & OF_EuthanizeMe)) obj->Destroy(); + if (obj != nullptr && !(obj->ObjectFlags & OF_EuthanizeMe)) obj->Destroy(); } r->mDObjects.Clear(); diff --git a/src/swrenderer/things/r_model.cpp b/src/swrenderer/things/r_model.cpp index 2d09ca276..025263e34 100644 --- a/src/swrenderer/things/r_model.cpp +++ b/src/swrenderer/things/r_model.cpp @@ -120,13 +120,17 @@ namespace swrenderer } SetTransform(); - PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true); + + if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] || !!(smf->flags & MDL_DONTCULLBACKFACES)) + PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true); } void SWModelRenderer::EndDrawModel(AActor *actor, FSpriteModelFrame *smf) { + if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] || !!(smf->flags & MDL_DONTCULLBACKFACES)) + PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false); + ModelActor = nullptr; - PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false); } IModelVertexBuffer *SWModelRenderer::CreateVertexBuffer(bool needindex, bool singleframe) @@ -185,14 +189,18 @@ namespace swrenderer ClipBottom = {}; SetTransform(); PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, true); - PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true); + + if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal]) + PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true); } void SWModelRenderer::EndDrawHUDModel(AActor *actor) { ModelActor = nullptr; PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, false); - PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false); + + if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal]) + PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false); } void SWModelRenderer::SetInterpolation(double interpolation) @@ -229,13 +237,7 @@ namespace swrenderer PolyDrawArgs args; args.SetLight(GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], true), lightlevel, Thread->Light->SpriteGlobVis(foggy), fullbrightSprite); - args.SetStyle(TriBlendMode::TextureOpaque); - - if (Thread->Viewport->RenderTarget->IsBgra()) - args.SetTexture((const uint8_t *)SkinTexture->GetPixelsBgra(), SkinTexture->GetWidth(), SkinTexture->GetHeight()); - else - args.SetTexture(SkinTexture->GetPixels(DefaultRenderStyle()), SkinTexture->GetWidth(), SkinTexture->GetHeight()); - + args.SetStyle(ModelActor->RenderStyle, ModelActor->Alpha, ModelActor->fillcolor, ModelActor->Translation, SkinTexture, fullbrightSprite); args.SetDepthTest(true); args.SetWriteDepth(true); args.SetWriteStencil(false); @@ -259,13 +261,7 @@ namespace swrenderer PolyDrawArgs args; args.SetLight(GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], true), lightlevel, Thread->Light->SpriteGlobVis(foggy), fullbrightSprite); - args.SetStyle(TriBlendMode::TextureOpaque); - - if (Thread->Viewport->RenderTarget->IsBgra()) - args.SetTexture((const uint8_t *)SkinTexture->GetPixelsBgra(), SkinTexture->GetWidth(), SkinTexture->GetHeight()); - else - args.SetTexture(SkinTexture->GetPixels(DefaultRenderStyle()), SkinTexture->GetWidth(), SkinTexture->GetHeight()); - + args.SetStyle(ModelActor->RenderStyle, ModelActor->Alpha, ModelActor->fillcolor, ModelActor->Translation, SkinTexture, fullbrightSprite); args.SetDepthTest(true); args.SetWriteDepth(true); args.SetWriteStencil(false); diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index 28f2bf5ed..2a49a2426 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -1440,19 +1440,18 @@ FString I_GetLongPathName(FString shortpath) return longpath; } -#if _MSC_VER == 1900 && defined(_USING_V110_SDK71_) +#ifdef _USING_V110_SDK71_ //========================================================================== // -// VS14Stat +// _stat64i32 // -// Work around an issue where stat doesn't work with v140_xp. This was -// supposedly fixed, but as of Update 1 continues to not function on XP. +// Work around an issue where stat() function doesn't work +// with Windows XP compatible toolset. +// It uses GetFileInformationByHandleEx() which requires Windows Vista. // //========================================================================== -#include - -int VS14Stat(const char *path, struct _stat64i32 *buffer) +int _stat64i32(const char *path, struct _stat64i32 *buffer) { WIN32_FILE_ATTRIBUTE_DATA data; if(!GetFileAttributesEx(path, GetFileExInfoStandard, &data))