qmlfrontend/renderer/tiled_image_item.cpp
author unC0Rr
Mon, 17 Feb 2025 16:37:59 +0100
branchqmlrenderer
changeset 16089 02304ad06381
permissions -rw-r--r--
Add TiledImageItem and a scene that represents hedgewars map
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16089
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
     1
#include "tiled_image_item.h"
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
     2
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
     3
#include <QSGImageNode>
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
     4
#include <QSGTexture>
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
     5
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
     6
TiledImageItem::TiledImageItem(QQuickItem *parent) : QQuickItem{parent} {
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
     7
  setFlag(ItemHasContents, true);
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
     8
  setFlag(ItemObservesViewport, true);
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
     9
}
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    10
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    11
TiledImageItem::~TiledImageItem() {}
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    12
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    13
void TiledImageItem::setImageData(int width, int height, uchar *pixels,
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    14
                                  QImage::Format format) {
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    15
  m_texture = QImage{pixels, width, height, width * 4, format};
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    16
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    17
  setImplicitWidth(width / window()->effectiveDevicePixelRatio());
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    18
  setImplicitHeight(height / window()->effectiveDevicePixelRatio());
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    19
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    20
  buildTiles();
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    21
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    22
  update();
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    23
}
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    24
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    25
void TiledImageItem::buildTiles() {
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    26
  m_tiles.clear();
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    27
  if (m_texture.isNull()) {
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    28
    return;
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    29
  }
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    30
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    31
  const auto imageWidth = m_texture.width();
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    32
  const auto imageHeight = m_texture.height();
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    33
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    34
  for (int y = 0; y < imageHeight; y += m_tileSize) {
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    35
    for (int x = 0; x < imageWidth; x += m_tileSize) {
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    36
      int w = qMin(m_tileSize, imageWidth - x);
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    37
      int h = qMin(m_tileSize, imageHeight - y);
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    38
      QImage tileImage{&m_texture.scanLine(y)[x * m_texture.depth() / 8],
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    39
                       m_tileSize, m_tileSize, m_texture.bytesPerLine(),
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    40
                       m_texture.format()};
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    41
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    42
      QRectF tileRect = QRect{x, y, w, h}.toRectF();
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    43
      tileRect.setTopLeft(tileRect.topLeft() /
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    44
                          window()->effectiveDevicePixelRatio());
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    45
      tileRect.setBottomRight(tileRect.bottomRight() /
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    46
                              window()->effectiveDevicePixelRatio());
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    47
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    48
      Tile tile;
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    49
      tile.outRect = tileRect;
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    50
      tile.image = tileImage;
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    51
      tile.dirty = true;
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    52
      m_tiles.emplace_back(std::move(tile));
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    53
    }
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    54
  }
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    55
}
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    56
int TiledImageItem::tileSize() const { return m_tileSize; }
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    57
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    58
void TiledImageItem::setTileSize(int newTileSize) {
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    59
  if (m_tileSize == newTileSize) {
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    60
    return;
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    61
  }
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    62
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    63
  m_tileSize = newTileSize;
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    64
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    65
  m_tiles.clear();
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    66
  m_dirty = true;
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    67
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    68
  Q_EMIT tileSizeChanged();
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    69
}
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    70
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    71
void TiledImageItem::test(const QString &fileName) {
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    72
  auto image = new QImage(fileName);
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    73
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    74
  setImageData(image->width(), image->height(), image->bits(), image->format());
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    75
}
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    76
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    77
QSGNode *TiledImageItem::updatePaintNode(QSGNode *oldNode,
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    78
                                         UpdatePaintNodeData *) {
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    79
  auto rootNode = oldNode;
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    80
  if (!rootNode) {
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    81
    rootNode = new QSGNode{};
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    82
  }
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    83
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    84
  if (!window()) {
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    85
    return rootNode;
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    86
  }
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    87
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    88
  const auto rect = clipRect();
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    89
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    90
  for (auto &tile : m_tiles) {
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    91
    if (!rect.intersects(tile.outRect)) {
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    92
      if (tile.node) {
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    93
        rootNode->removeChildNode(tile.node.get());
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    94
        tile.node.reset();
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    95
      }
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    96
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    97
      continue;
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    98
    }
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
    99
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   100
    if (tile.dirty) {
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   101
      tile.texture.reset(window()->createTextureFromImage(tile.image));
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   102
      if (tile.node) {
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   103
        tile.node->setTexture(tile.texture.get());
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   104
      }
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   105
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   106
      tile.dirty = false;
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   107
    }
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   108
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   109
    if (!tile.node) {
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   110
      tile.node.reset(window()->createImageNode());
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   111
      tile.node->setRect(tile.outRect);
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   112
      tile.node->setTexture(tile.texture.get());
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   113
      rootNode->appendChildNode(tile.node.get());
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   114
    }
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   115
  }
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   116
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   117
  return rootNode;
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   118
}
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   119
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   120
TiledImageItem::Tile::Tile(Tile &&other) noexcept
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   121
    : outRect{other.outRect},
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   122
      image{std::move(other.image)},
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   123
      dirty{other.dirty},
02304ad06381 Add TiledImageItem and a scene that represents hedgewars map
unC0Rr
parents:
diff changeset
   124
      texture{std::move(other.texture)} {}