Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tiledquickplugin: only render visible tiles #2772

Merged
merged 5 commits into from
Mar 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions src/libtiled/hexagonalrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,17 @@ void HexagonalRenderer::drawGrid(QPainter *painter, const QRectF &exposed,
void HexagonalRenderer::drawTileLayer(QPainter *painter,
const TileLayer *layer,
const QRectF &exposed) const
{
CellRenderer renderer(painter, this, layer->effectiveTintColor(), CellRenderer::HexagonalCells);
auto tileRenderFunction = [&renderer](const Cell &cell, const QPointF &pos, const QSizeF &size) {
renderer.render(cell, pos, size, CellRenderer::BottomLeft);
};
drawTileLayer(layer, tileRenderFunction, exposed);
}

void HexagonalRenderer::drawTileLayer(const TileLayer *layer,
const RenderTileCallback &renderTile,
const QRectF &exposed) const
{
const RenderParams p(map());

Expand Down Expand Up @@ -307,8 +318,6 @@ void HexagonalRenderer::drawTileLayer(QPainter *painter,
if (inLeftHalf)
startTile.rx()--;

CellRenderer renderer(painter, this, layer->effectiveTintColor(), CellRenderer::HexagonalCells);

const int endX = map()->infinite() ? layer->bounds().right() - layer->x() + 1 : layer->width();
const int endY = map()->infinite() ? layer->bounds().bottom() - layer->y() + 1 : layer->height();

Expand All @@ -331,9 +340,9 @@ void HexagonalRenderer::drawTileLayer(QPainter *painter,
const Cell &cell = layer->cellAt(rowTile);

if (!cell.isEmpty()) {
Tile *tile = cell.tile();
QSize size = tile ? tile->size() : map()->tileSize();
renderer.render(cell, rowPos, size, CellRenderer::BottomLeft);
const Tile *tile = cell.tile();
const QSize size = tile ? tile->size() : map()->tileSize();
renderTile(cell, rowPos, size);
}

rowPos.rx() += p.tileWidth + p.sideLengthX;
Expand Down Expand Up @@ -376,9 +385,9 @@ void HexagonalRenderer::drawTileLayer(QPainter *painter,
const Cell &cell = layer->cellAt(rowTile);

if (!cell.isEmpty()) {
Tile *tile = cell.tile();
QSize size = tile ? tile->size() : map()->tileSize();
renderer.render(cell, rowPos, size, CellRenderer::BottomLeft);
const Tile *tile = cell.tile();
const QSize size = tile ? tile->size() : map()->tileSize();
renderTile(cell, rowPos, size);
}

rowPos.rx() += p.tileWidth + p.sideLengthX;
Expand Down
4 changes: 4 additions & 0 deletions src/libtiled/hexagonalrenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ class TILEDSHARED_EXPORT HexagonalRenderer : public OrthogonalRenderer
void drawTileLayer(QPainter *painter, const TileLayer *layer,
const QRectF &exposed = QRectF()) const override;

void drawTileLayer(const TileLayer *layer,
const RenderTileCallback &renderTile,
const QRectF &exposed = QRectF()) const override;

void drawTileSelection(QPainter *painter,
const QRegion &region,
const QColor &color,
Expand Down
20 changes: 14 additions & 6 deletions src/libtiled/isometricrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,17 @@ void IsometricRenderer::drawGrid(QPainter *painter, const QRectF &rect,
void IsometricRenderer::drawTileLayer(QPainter *painter,
const TileLayer *layer,
const QRectF &exposed) const
{
CellRenderer renderer(painter, this, layer->effectiveTintColor());
auto tileRenderFunction = [&renderer](const Cell &cell, const QPointF &pos, const QSizeF &size) {
renderer.render(cell, pos, size, CellRenderer::BottomLeft);
};
drawTileLayer(layer, tileRenderFunction, exposed);
}

void IsometricRenderer::drawTileLayer(const TileLayer *layer,
const RenderTileCallback &renderTile,
const QRectF &exposed) const
{
const int tileWidth = map()->tileWidth();
const int tileHeight = map()->tileHeight();
Expand Down Expand Up @@ -318,8 +329,6 @@ void IsometricRenderer::drawTileLayer(QPainter *painter,
// Determine whether the current row is shifted half a tile to the right
bool shifted = inUpperHalf ^ inLeftHalf;

CellRenderer renderer(painter, this, layer->effectiveTintColor());

for (int y = startPos.y() * 2; y - tileHeight * 2 < rect.bottom() * 2;
y += tileHeight)
{
Expand All @@ -328,10 +337,9 @@ void IsometricRenderer::drawTileLayer(QPainter *painter,
for (int x = startPos.x(); x < rect.right(); x += tileWidth) {
const Cell &cell = layer->cellAt(columnItr);
if (!cell.isEmpty()) {
Tile *tile = cell.tile();
QSize size = (tile && !tile->image().isNull()) ? tile->size() : map()->tileSize();
renderer.render(cell, QPointF(x, (qreal)y / 2), size,
CellRenderer::BottomLeft);
const Tile *tile = cell.tile();
const QSize size = (tile && !tile->image().isNull()) ? tile->size() : map()->tileSize();
renderTile(cell, QPointF(x, (qreal)y / 2), size);
}

// Advance to the next column
Expand Down
4 changes: 4 additions & 0 deletions src/libtiled/isometricrenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ class TILEDSHARED_EXPORT IsometricRenderer final : public MapRenderer
void drawTileLayer(QPainter *painter, const TileLayer *layer,
const QRectF &exposed = QRectF()) const override;

void drawTileLayer(const TileLayer *layer,
const RenderTileCallback &renderTile,
const QRectF &exposed = QRectF()) const override;

void drawTileSelection(QPainter *painter,
const QRegion &region,
const QColor &color,
Expand Down
14 changes: 14 additions & 0 deletions src/libtiled/maprenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

#include "tiled_global.h"

#include <functional>

#include <QPainter>

namespace Tiled {
Expand Down Expand Up @@ -130,6 +132,8 @@ class TILEDSHARED_EXPORT MapRenderer
virtual void drawGrid(QPainter *painter, const QRectF &rect,
QColor gridColor = Qt::black) const = 0;

typedef std::function<void(const Cell &, const QPointF &, const QSizeF &)> RenderTileCallback;

/**
* Draws the given \a layer using the given \a painter.
*
Expand All @@ -139,6 +143,16 @@ class TILEDSHARED_EXPORT MapRenderer
virtual void drawTileLayer(QPainter *painter, const TileLayer *layer,
const QRectF &exposed = QRectF()) const = 0;

/**
* Draws the given \a layer using the given \a renderTile callback.
*
* Optionally, you can pass in the \a exposed rect (of pixels), so that
* only tiles that can be visible in this area will be drawn.
*/
virtual void drawTileLayer(const TileLayer *layer,
const RenderTileCallback &renderTile,
const QRectF &exposed = QRectF()) const = 0;

/**
* Draws the tile selection given by \a region in the specified \a color.
*
Expand Down
29 changes: 14 additions & 15 deletions src/libtiled/orthogonalrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,17 @@ void OrthogonalRenderer::drawTileLayer(QPainter *painter,
const TileLayer *layer,
const QRectF &exposed) const
{
CellRenderer renderer(painter, this, layer->effectiveTintColor());
auto tileRenderFunction = [&renderer](const Cell &cell, const QPointF &pos, const QSizeF &size) {
renderer.render(cell, pos, size, CellRenderer::BottomLeft);
};
drawTileLayer(layer, tileRenderFunction, exposed);
}

void OrthogonalRenderer::drawTileLayer(const TileLayer *layer,
const RenderTileCallback &renderTile,
const QRectF &exposed) const
{

const int tileWidth = map()->tileWidth();
const int tileHeight = map()->tileHeight();
Expand Down Expand Up @@ -302,11 +313,6 @@ void OrthogonalRenderer::drawTileLayer(QPainter *painter,
if (startX > endX || startY > endY)
return;

const QTransform savedTransform = painter->transform();
painter->translate(layerPos);

CellRenderer renderer(painter, this, layer->effectiveTintColor());

Map::RenderOrder renderOrder = map()->renderOrder();

int incX = 1, incY = 1;
Expand Down Expand Up @@ -338,18 +344,11 @@ void OrthogonalRenderer::drawTileLayer(QPainter *painter,
if (cell.isEmpty())
continue;

Tile *tile = cell.tile();
QSize size = (tile && !tile->image().isNull()) ? tile->size() : map()->tileSize();
renderer.render(cell,
QPointF(x * tileWidth, (y + 1) * tileHeight),
size,
CellRenderer::BottomLeft);
const Tile *tile = cell.tile();
const QSize size = (tile && !tile->image().isNull()) ? tile->size() : map()->tileSize();
renderTile(cell, layerPos + QPointF(x * tileWidth, (y + 1) * tileHeight), size);
}
}

renderer.flush();

painter->setTransform(savedTransform);
}

void OrthogonalRenderer::drawTileSelection(QPainter *painter,
Expand Down
4 changes: 4 additions & 0 deletions src/libtiled/orthogonalrenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ class TILEDSHARED_EXPORT OrthogonalRenderer : public MapRenderer
void drawTileLayer(QPainter *painter, const TileLayer *layer,
const QRectF &exposed = QRectF()) const override;

void drawTileLayer(const TileLayer *layer,
const RenderTileCallback &renderTile,
const QRectF &exposed = QRectF()) const override;

void drawTileSelection(QPainter *painter,
const QRegion &region,
const QColor &color,
Expand Down
40 changes: 10 additions & 30 deletions src/tiledquickplugin/mapitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@

#include "tilelayeritem.h"

#include "hexagonalrenderer.h"
#include "isometricrenderer.h"
#include "map.h"
#include "orthogonalrenderer.h"
#include "staggeredrenderer.h"
#include "tilelayer.h"

#include <cmath>
Expand Down Expand Up @@ -55,34 +57,6 @@ void MapItem::setVisibleArea(const QRectF &visibleArea)
emit visibleAreaChanged();
}

/**
* Determines the rectangle of visible tiles of the given tile \a layer, based
* on the visible area of this MapItem instance.
*
* Only works for orthogonal maps.
*/
QRect MapItem::visibleTileArea(const Tiled::TileLayer *layer) const
{
const int tileWidth = mMap->tileWidth();
const int tileHeight = mMap->tileHeight();

QMargins drawMargins = layer->drawMargins();
drawMargins.setTop(drawMargins.top() - tileHeight);
drawMargins.setRight(drawMargins.right() - tileWidth);

QRectF rect = visibleArea().adjusted(-drawMargins.right(),
-drawMargins.bottom(),
drawMargins.left(),
drawMargins.top());

int startX = qMax((int) rect.x() / tileWidth, 0);
int startY = qMax((int) rect.y() / tileHeight, 0);
int endX = qMin((int) std::ceil(rect.right()) / tileWidth, layer->width() - 1);
int endY = qMin((int) std::ceil(rect.bottom()) / tileHeight, layer->height() - 1);

return QRect(QPoint(startX, startY), QPoint(endX, endY));
}

QRectF MapItem::boundingRect() const
{
if (!mRenderer)
Expand Down Expand Up @@ -182,11 +156,17 @@ void MapItem::refresh()
return;

switch (mMap->orientation()) {
default:
mRenderer = std::make_unique<Tiled::OrthogonalRenderer>(mMap);
break;
case Tiled::Map::Isometric:
mRenderer = std::make_unique<Tiled::IsometricRenderer>(mMap);
break;
default:
mRenderer = std::make_unique<Tiled::OrthogonalRenderer>(mMap);
case Tiled::Map::Staggered:
mRenderer = std::make_unique<Tiled::StaggeredRenderer>(mMap);
break;
case Tiled::Map::Hexagonal:
mRenderer = std::make_unique<Tiled::HexagonalRenderer>(mMap);
break;
}

Expand Down
3 changes: 0 additions & 3 deletions src/tiledquickplugin/mapitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
namespace Tiled {
class Map;
class MapRenderer;
class Tileset;
class TileLayer;
} // namespace Tiled

namespace TiledQuick {
Expand All @@ -55,7 +53,6 @@ class MapItem : public QQuickItem

const QRectF &visibleArea() const;
void setVisibleArea(const QRectF &visibleArea);
QRect visibleTileArea(const Tiled::TileLayer *layer) const;

QRectF boundingRect() const;

Expand Down
Loading