Skip to content

Commit

Permalink
tiledquickplugin: Only render visible tiles for all orientations (map…
Browse files Browse the repository at this point in the history
…editor#2772)

This change adds support for staggered and hexagonal maps to Tiled 
Quick, as well as making sure only visible tiles are rendered, reusing
the rendering code from the MapRenderer.

The small optimization that was used for orthogonal tile layers was
dropped for the sake of simplicity. It is not expected to make much of
an impact.

Fixes mapeditor#2769

Co-authored-by: Thorbjørn Lindeijer <[email protected]>
  • Loading branch information
mitchcurtis and bjorn authored Mar 18, 2020
1 parent adc559a commit d3badef
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 247 deletions.
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

0 comments on commit d3badef

Please sign in to comment.