mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 19:13:07 +01:00
Merge pull request #24304 from mixiate/fix-24303
Fix #24303: Track pieces do not draw in the ride construction window
This commit is contained in:
@@ -2670,6 +2670,11 @@ namespace OpenRCT2::Ui::Windows
|
||||
dpi.x += rotatedScreenCoords.x - widgetWidth / 2;
|
||||
dpi.y += rotatedScreenCoords.y - widgetHeight / 2 - 16;
|
||||
|
||||
dpi.cullingX = dpi.x;
|
||||
dpi.cullingY = dpi.y;
|
||||
dpi.cullingWidth = dpi.width;
|
||||
dpi.cullingHeight = dpi.height;
|
||||
|
||||
DrawTrackPieceHelper(dpi, rideIndex, trackType, trackDirection, liftHillAndInvertedState, { 4096, 4096 }, 1024);
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,10 @@ struct DrawPixelInfo
|
||||
int32_t width{};
|
||||
int32_t height{};
|
||||
int32_t pitch{}; // note: this is actually (pitch - width)
|
||||
int32_t cullingX{};
|
||||
int32_t cullingY{};
|
||||
int32_t cullingWidth{};
|
||||
int32_t cullingHeight{};
|
||||
ZoomLevel zoom_level{};
|
||||
|
||||
// Last position of drawn text.
|
||||
|
||||
@@ -305,6 +305,11 @@ namespace OpenRCT2::Drawing::LightFx
|
||||
dpi.height = 1;
|
||||
dpi.width = 1;
|
||||
|
||||
dpi.cullingX = dpi.x;
|
||||
dpi.cullingY = dpi.y;
|
||||
dpi.cullingWidth = dpi.width;
|
||||
dpi.cullingHeight = dpi.height;
|
||||
|
||||
PaintSession* session = PaintSessionAlloc(dpi, w->viewport->flags, w->viewport->rotation);
|
||||
PaintSessionGenerate(*session);
|
||||
PaintSessionArrange(*session);
|
||||
|
||||
@@ -1063,6 +1063,15 @@ namespace OpenRCT2
|
||||
}
|
||||
columnDpi.width = paintRight - columnDpi.x;
|
||||
|
||||
// culling sprites outside the clipped column causes sorting differences between invalidation blocks
|
||||
// not culling sprites outside the full column width also causes a different kind of glitching
|
||||
constexpr int32_t cullingY = ZoomLevel::max().ApplyInversedTo(std::numeric_limits<int32_t>::max()) / 2;
|
||||
|
||||
columnDpi.cullingX = floor2(columnDpi.x, columnWidth);
|
||||
columnDpi.cullingY = -cullingY;
|
||||
columnDpi.cullingWidth = columnWidth;
|
||||
columnDpi.cullingHeight = cullingY * 2;
|
||||
|
||||
if (useMultithreading)
|
||||
{
|
||||
_paintJobs->AddTask([session]() -> void { ViewportFillColumn(*session); });
|
||||
@@ -1813,6 +1822,11 @@ namespace OpenRCT2
|
||||
dpi.height = 1;
|
||||
dpi.width = 1;
|
||||
|
||||
dpi.cullingX = dpi.x;
|
||||
dpi.cullingY = dpi.y;
|
||||
dpi.cullingWidth = dpi.width;
|
||||
dpi.cullingHeight = dpi.height;
|
||||
|
||||
PaintSession* session = PaintSessionAlloc(dpi, viewport->flags, viewport->rotation);
|
||||
PaintSessionGenerate(*session);
|
||||
PaintSessionArrange(*session);
|
||||
|
||||
@@ -103,23 +103,42 @@ static void PaintSessionAddPSToQuadrant(PaintSession& session, PaintStruct* ps)
|
||||
session.QuadrantFrontIndex = std::max(session.QuadrantFrontIndex, paintQuadrantIndex);
|
||||
}
|
||||
|
||||
static constexpr bool imageWithinColumn(const ScreenCoordsXY& imagePos, const G1Element& g1, const DrawPixelInfo& dpi)
|
||||
static constexpr bool imageWithinDPI(const ScreenCoordsXY& imagePos, const G1Element& g1, const DrawPixelInfo& dpi)
|
||||
{
|
||||
const int32_t left = imagePos.x + g1.x_offset;
|
||||
const int32_t bottom = imagePos.y + g1.y_offset;
|
||||
|
||||
const int32_t right = left + g1.width;
|
||||
const int32_t top = bottom + g1.height;
|
||||
|
||||
const int32_t columnWidth = dpi.zoom_level.ApplyInversedTo(kCoordsXYStep);
|
||||
const int32_t alignedX = floor2(dpi.x, columnWidth);
|
||||
|
||||
// check if a sprite is within the full unclipped column width
|
||||
// culling sprites outside the clipped column causes sorting differences between invalidation blocks
|
||||
// not culling sprites outside the full column width also causes a different kind of glitching
|
||||
|
||||
if (dpi.zoom_level.ApplyInversedTo(right) <= alignedX)
|
||||
return false;
|
||||
if (dpi.zoom_level.ApplyInversedTo(left) >= alignedX + columnWidth)
|
||||
return false;
|
||||
|
||||
// mber: It is possible to use only the bottom else block here if you change <= and >= to simply < and >.
|
||||
// However, since this is used to cull paint structs, I'd prefer to keep the condition strict and calculate
|
||||
// the culling differently for minifying and magnifying.
|
||||
const auto zoom = dpi.zoom_level;
|
||||
if (zoom > ZoomLevel{ 0 })
|
||||
{
|
||||
const int32_t x = zoom.ApplyTo(dpi.cullingX);
|
||||
const int32_t y = zoom.ApplyTo(dpi.cullingY);
|
||||
if (right <= x)
|
||||
return false;
|
||||
if (top <= y)
|
||||
return false;
|
||||
if (left >= x + zoom.ApplyTo(dpi.cullingWidth))
|
||||
return false;
|
||||
if (bottom >= y + zoom.ApplyTo(dpi.cullingHeight))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (zoom.ApplyInversedTo(right) <= dpi.cullingX)
|
||||
return false;
|
||||
if (zoom.ApplyInversedTo(top) <= dpi.cullingY)
|
||||
return false;
|
||||
if (zoom.ApplyInversedTo(left) >= dpi.cullingX + dpi.cullingWidth)
|
||||
return false;
|
||||
if (zoom.ApplyInversedTo(bottom) >= dpi.cullingY + dpi.cullingHeight)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -167,7 +186,7 @@ static PaintStruct* CreateNormalPaintStruct(
|
||||
|
||||
const auto imagePos = Translate3DTo2DWithZ(session.CurrentRotation, swappedRotCoord);
|
||||
|
||||
if (!imageWithinColumn(imagePos, *g1, session.DPI))
|
||||
if (!imageWithinDPI(imagePos, *g1, session.DPI))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@@ -215,7 +234,7 @@ static PaintStruct* CreateNormalPaintStructHeight(
|
||||
|
||||
const auto imagePos = Translate3DTo2DWithZ(session.CurrentRotation, swappedRotCoord);
|
||||
|
||||
if (!imageWithinColumn(imagePos, *g1, session.DPI))
|
||||
if (!imageWithinDPI(imagePos, *g1, session.DPI))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user