mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-06 06:32:56 +01:00
Rewrite ViewportPaint to handle new DPI coords
This commit is contained in:
@@ -707,10 +707,10 @@ void OpenGLDrawingContext::DrawSprite(DrawPixelInfo& dpi, const ImageId imageId,
|
||||
{
|
||||
DrawPixelInfo zoomedDPI;
|
||||
zoomedDPI.bits = dpi.bits;
|
||||
zoomedDPI.SetX(dpi.zoom_level.ApplyInversedTo(dpi.WorldX()) / 2);
|
||||
zoomedDPI.SetY(dpi.zoom_level.ApplyInversedTo(dpi.WorldY()) / 2);
|
||||
zoomedDPI.SetHeight(dpi.zoom_level.ApplyInversedTo(dpi.WorldHeight()) / 2);
|
||||
zoomedDPI.SetWidth(dpi.zoom_level.ApplyInversedTo(dpi.WorldWidth()) / 2);
|
||||
zoomedDPI.SetX(dpi.ScreenX());
|
||||
zoomedDPI.SetY(dpi.ScreenY());
|
||||
zoomedDPI.SetHeight(dpi.ScreenHeight());
|
||||
zoomedDPI.SetWidth(dpi.ScreenWidth());
|
||||
zoomedDPI.pitch = dpi.pitch;
|
||||
zoomedDPI.zoom_level = dpi.zoom_level - 1;
|
||||
DrawSprite(zoomedDPI, imageId.WithIndex(imageId.GetIndex() - g1Element->zoomed_offset), x >> 1, y >> 1);
|
||||
|
||||
@@ -1299,9 +1299,7 @@ namespace OpenRCT2::Ui::Windows
|
||||
*/
|
||||
void WindowDrawViewport(DrawPixelInfo& dpi, WindowBase& w)
|
||||
{
|
||||
ViewportRender(
|
||||
dpi, w.viewport,
|
||||
{ { dpi.ScreenX(), dpi.ScreenY() }, { dpi.ScreenX() + dpi.ScreenWidth(), dpi.ScreenY() + dpi.ScreenHeight() } });
|
||||
ViewportRender(dpi, w.viewport);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -48,10 +48,7 @@ namespace OpenRCT2::Ui::Windows
|
||||
|
||||
void OnDraw(DrawPixelInfo& dpi) override
|
||||
{
|
||||
ViewportRender(
|
||||
dpi, viewport,
|
||||
{ { dpi.ScreenX(), dpi.ScreenY() },
|
||||
{ dpi.ScreenX() + dpi.ScreenWidth(), dpi.ScreenY() + dpi.ScreenHeight() } });
|
||||
ViewportRender(dpi, viewport);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -319,7 +319,7 @@ static void RenderViewport(IDrawingEngine* drawingEngine, const Viewport& viewpo
|
||||
drawingEngine = tempDrawingEngine.get();
|
||||
}
|
||||
dpi.DrawingEngine = drawingEngine;
|
||||
ViewportRender(dpi, &viewport, { { 0, 0 }, { viewport.width, viewport.height } });
|
||||
ViewportRender(dpi, &viewport);
|
||||
}
|
||||
|
||||
void ScreenshotGiant()
|
||||
|
||||
@@ -74,7 +74,7 @@ InteractionInfo::InteractionInfo(const PaintStruct* ps)
|
||||
}
|
||||
|
||||
static void ViewportPaintWeatherGloom(DrawPixelInfo& dpi);
|
||||
static void ViewportPaint(const Viewport* viewport, DrawPixelInfo& dpi, const ScreenRect& screenRect);
|
||||
static void ViewportPaint(const Viewport* viewport, DrawPixelInfo& dpi);
|
||||
static void ViewportUpdateFollowSprite(WindowBase* window);
|
||||
static void ViewportUpdateSmartFollowEntity(WindowBase* window);
|
||||
static void ViewportUpdateSmartFollowStaff(WindowBase* window, const Staff& peep);
|
||||
@@ -925,20 +925,18 @@ void ViewportRotateAll(int32_t direction)
|
||||
* edi: dpi
|
||||
* ebp: bottom
|
||||
*/
|
||||
void ViewportRender(DrawPixelInfo& dpi, const Viewport* viewport, const ScreenRect& screenRect)
|
||||
void ViewportRender(DrawPixelInfo& dpi, const Viewport* viewport)
|
||||
{
|
||||
if (viewport->flags & VIEWPORT_FLAG_RENDERING_INHIBITED)
|
||||
return;
|
||||
|
||||
auto [topLeft, bottomRight] = screenRect;
|
||||
|
||||
if (bottomRight.x <= viewport->pos.x)
|
||||
if (dpi.ScreenX() + dpi.ScreenWidth() <= viewport->pos.x)
|
||||
return;
|
||||
if (bottomRight.y <= viewport->pos.y)
|
||||
if (dpi.ScreenY() + dpi.ScreenHeight() <= viewport->pos.y)
|
||||
return;
|
||||
if (topLeft.x >= viewport->pos.x + viewport->width)
|
||||
if (dpi.ScreenX() >= viewport->pos.x + viewport->width)
|
||||
return;
|
||||
if (topLeft.y >= viewport->pos.y + viewport->height)
|
||||
if (dpi.ScreenY() >= viewport->pos.y + viewport->height)
|
||||
return;
|
||||
|
||||
#ifdef DEBUG_SHOW_DIRTY_BOX
|
||||
@@ -946,19 +944,7 @@ void ViewportRender(DrawPixelInfo& dpi, const Viewport* viewport, const ScreenRe
|
||||
const auto dirtyBoxTopRight = bottomRight - ScreenCoordsXY{ 1, 1 };
|
||||
#endif
|
||||
|
||||
topLeft -= viewport->pos;
|
||||
topLeft = ScreenCoordsXY{
|
||||
viewport->zoom.ApplyTo(std::max(topLeft.x, 0)),
|
||||
viewport->zoom.ApplyTo(std::max(topLeft.y, 0)),
|
||||
} + viewport->viewPos;
|
||||
|
||||
bottomRight -= viewport->pos;
|
||||
bottomRight = ScreenCoordsXY{
|
||||
viewport->zoom.ApplyTo(std::min(bottomRight.x, viewport->width)),
|
||||
viewport->zoom.ApplyTo(std::min(bottomRight.y, viewport->height)),
|
||||
} + viewport->viewPos;
|
||||
|
||||
ViewportPaint(viewport, dpi, { topLeft, bottomRight });
|
||||
ViewportPaint(viewport, dpi);
|
||||
|
||||
#ifdef DEBUG_SHOW_DIRTY_BOX
|
||||
// FIXME g_viewport_list doesn't exist anymore
|
||||
@@ -1016,47 +1002,28 @@ static void ViewportPaintColumn(PaintSession& session)
|
||||
* edi: dpi
|
||||
* ebp: bottom
|
||||
*/
|
||||
static void ViewportPaint(const Viewport* viewport, DrawPixelInfo& dpi, const ScreenRect& screenRect)
|
||||
static void ViewportPaint(const Viewport* viewport, DrawPixelInfo& dpi)
|
||||
{
|
||||
PROFILED_FUNCTION();
|
||||
|
||||
const uint32_t viewFlags = viewport->flags;
|
||||
if (viewFlags & VIEWPORT_FLAG_RENDERING_INHIBITED)
|
||||
return;
|
||||
const int32_t offsetX = dpi.ScreenX() - viewport->pos.x;
|
||||
const int32_t offsetY = dpi.ScreenY() - viewport->pos.y;
|
||||
const int32_t worldX = viewport->zoom.ApplyInversedTo(viewport->viewPos.x) + std::max(0, offsetX);
|
||||
const int32_t worldY = viewport->zoom.ApplyInversedTo(viewport->viewPos.y) + std::max(0, offsetY);
|
||||
const int32_t width = std::min(viewport->pos.x + viewport->width, dpi.ScreenX() + dpi.ScreenWidth())
|
||||
- std::max(viewport->pos.x, dpi.ScreenX());
|
||||
const int32_t height = std::min(viewport->pos.y + viewport->height, dpi.ScreenY() + dpi.ScreenHeight())
|
||||
- std::max(viewport->pos.y, dpi.ScreenY());
|
||||
|
||||
uint32_t width = screenRect.GetWidth();
|
||||
uint32_t height = screenRect.GetHeight();
|
||||
// TODO: (mber) remove this masking code.
|
||||
const uint32_t bitmask = viewport->zoom >= ZoomLevel{ 0 } ? 0xFFFFFFFF & (viewport->zoom.ApplyTo(0xFFFFFFFF)) : 0xFFFFFFFF;
|
||||
ScreenCoordsXY topLeft = screenRect.Point1;
|
||||
|
||||
width &= bitmask;
|
||||
height &= bitmask;
|
||||
topLeft.x &= bitmask;
|
||||
topLeft.y &= bitmask;
|
||||
|
||||
auto x = topLeft.x - static_cast<int32_t>(viewport->viewPos.x & bitmask);
|
||||
x = viewport->zoom.ApplyInversedTo(x);
|
||||
x += viewport->pos.x;
|
||||
|
||||
auto y = topLeft.y - static_cast<int32_t>(viewport->viewPos.y & bitmask);
|
||||
y = viewport->zoom.ApplyInversedTo(y);
|
||||
y += viewport->pos.y;
|
||||
|
||||
DrawPixelInfo dpi1;
|
||||
dpi1.DrawingEngine = dpi.DrawingEngine;
|
||||
dpi1.bits = dpi.bits + (x - dpi.ScreenX()) + ((y - dpi.ScreenY()) * dpi.LineStride());
|
||||
dpi1.SetX(viewport->zoom.ApplyInversedTo(topLeft.x));
|
||||
dpi1.SetY(viewport->zoom.ApplyInversedTo(topLeft.y));
|
||||
dpi1.SetWidth(viewport->zoom.ApplyInversedTo(width));
|
||||
dpi1.SetHeight(viewport->zoom.ApplyInversedTo(height));
|
||||
dpi1.pitch = dpi.LineStride() - viewport->zoom.ApplyInversedTo(width);
|
||||
dpi1.zoom_level = viewport->zoom;
|
||||
|
||||
// make sure, the compare operation is done in int32_t to avoid the loop becoming an infinite loop.
|
||||
// this as well as the [x += 32] in the loop causes signed integer overflow -> undefined behaviour.
|
||||
auto rightBorder = dpi1.WorldX() + dpi1.WorldWidth();
|
||||
auto alignedX = Floor2(dpi1.WorldX(), 32);
|
||||
DrawPixelInfo worldDpi;
|
||||
worldDpi.DrawingEngine = dpi.DrawingEngine;
|
||||
worldDpi.bits = dpi.bits + std::max(0, -offsetX) + std::max(0, -offsetY) * dpi.LineStride();
|
||||
worldDpi.SetX(worldX);
|
||||
worldDpi.SetY(worldY);
|
||||
worldDpi.SetWidth(width);
|
||||
worldDpi.SetHeight(height);
|
||||
worldDpi.pitch = dpi.LineStride() - worldDpi.ScreenWidth();
|
||||
worldDpi.zoom_level = viewport->zoom;
|
||||
|
||||
_paintColumns.clear();
|
||||
|
||||
@@ -1076,30 +1043,34 @@ static void ViewportPaint(const Viewport* viewport, DrawPixelInfo& dpi, const Sc
|
||||
useParallelDrawing = true;
|
||||
}
|
||||
|
||||
const int32_t columnWidth = worldDpi.zoom_level.ApplyInversedTo(kCoordsXYStep);
|
||||
const int32_t rightBorder = worldDpi.ScreenX() + worldDpi.ScreenWidth();
|
||||
const int32_t alignedX = Floor2(worldDpi.ScreenX(), columnWidth);
|
||||
|
||||
// Generate and sort columns.
|
||||
for (x = alignedX; x < rightBorder; x += 32)
|
||||
for (int32_t x = alignedX; x < rightBorder; x += columnWidth)
|
||||
{
|
||||
PaintSession* session = PaintSessionAlloc(dpi1, viewFlags, viewport->rotation);
|
||||
PaintSession* session = PaintSessionAlloc(worldDpi, viewport->flags, viewport->rotation);
|
||||
_paintColumns.push_back(session);
|
||||
|
||||
DrawPixelInfo& dpi2 = session->DPI;
|
||||
if (x >= dpi2.WorldX())
|
||||
DrawPixelInfo& columnDpi = session->DPI;
|
||||
if (x >= columnDpi.ScreenX())
|
||||
{
|
||||
auto leftPitch = x - dpi2.WorldX();
|
||||
dpi2.SetWidth(dpi2.ScreenWidth() - dpi2.zoom_level.ApplyInversedTo(leftPitch));
|
||||
dpi2.bits += dpi2.zoom_level.ApplyInversedTo(leftPitch);
|
||||
dpi2.pitch += dpi2.zoom_level.ApplyInversedTo(leftPitch);
|
||||
dpi2.SetX(dpi2.zoom_level.ApplyInversedTo(x));
|
||||
const int32_t leftPitch = x - columnDpi.ScreenX();
|
||||
columnDpi.SetWidth(columnDpi.ScreenWidth() - leftPitch);
|
||||
columnDpi.bits += leftPitch;
|
||||
columnDpi.pitch += leftPitch;
|
||||
columnDpi.SetX(x);
|
||||
}
|
||||
|
||||
auto paintRight = dpi2.WorldX() + dpi2.WorldWidth();
|
||||
if (paintRight >= x + 32)
|
||||
int32_t paintRight = columnDpi.ScreenX() + columnDpi.ScreenWidth();
|
||||
if (paintRight >= x + columnWidth)
|
||||
{
|
||||
auto rightPitch = paintRight - x - 32;
|
||||
const int32_t rightPitch = paintRight - x - columnWidth;
|
||||
paintRight -= rightPitch;
|
||||
dpi2.pitch += dpi2.zoom_level.ApplyInversedTo(rightPitch);
|
||||
columnDpi.pitch += rightPitch;
|
||||
}
|
||||
dpi2.SetWidth(dpi2.zoom_level.ApplyInversedTo(paintRight - dpi2.WorldX()));
|
||||
columnDpi.SetWidth(paintRight - columnDpi.ScreenX());
|
||||
|
||||
if (useMultithreading)
|
||||
{
|
||||
|
||||
@@ -140,7 +140,7 @@ void ViewportUpdatePosition(WindowBase* window);
|
||||
void ViewportUpdateSmartFollowGuest(WindowBase* window, const Guest& peep);
|
||||
void ViewportRotateSingle(WindowBase* window, int32_t direction);
|
||||
void ViewportRotateAll(int32_t direction);
|
||||
void ViewportRender(DrawPixelInfo& dpi, const Viewport* viewport, const ScreenRect& screenRect);
|
||||
void ViewportRender(DrawPixelInfo& dpi, const Viewport* viewport);
|
||||
|
||||
CoordsXYZ ViewportAdjustForMapHeight(const ScreenCoordsXY& startCoords, uint8_t rotation);
|
||||
|
||||
|
||||
@@ -2119,7 +2119,6 @@ void TrackDesignDrawPreview(TrackDesign& td, uint8_t* pixels)
|
||||
view.flags = VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_HIDE_ENTITIES;
|
||||
|
||||
DrawPixelInfo dpi;
|
||||
// dpi.zoom_level = zoom_level; // TODO (mber) this can be removed I think
|
||||
dpi.SetX(0);
|
||||
dpi.SetY(0);
|
||||
dpi.SetWidth(370);
|
||||
@@ -2135,7 +2134,7 @@ void TrackDesignDrawPreview(TrackDesign& td, uint8_t* pixels)
|
||||
{
|
||||
view.viewPos = Translate3DTo2DWithZ(i, centre) - offset;
|
||||
view.rotation = i;
|
||||
ViewportRender(dpi, &view, { {}, ScreenCoordsXY{ size_x, size_y } });
|
||||
ViewportRender(dpi, &view);
|
||||
|
||||
dpi.bits += kTrackPreviewImageSize;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user