[Qt-interest] Bug? Rendering artifacts with antialising and zooming of tiled pixmap backgrounds

Johannes Kleimola johannes at kleimola.fi
Sun Nov 22 13:16:15 CET 2009


Hi!

When constructing a QGraphicsScene with a customized background of 
pixmap tiles and doing zoom-in or zoom-out in the viewport, all 
QGraphicsItems that are moved around above the background and also the 
default rubberband selector leaves rendering artifacts on the tile 
boundaries if the setRenderHints(QPainter::Antialiasing) is set 
regardless of whether 
setOptimizationFlag(QGraphicsView::DontAdjustForAntialiasing) is 
disabled by default or by setting it to false. Removing the antialiasing 
renderhint removes the artifacts. Enabling 
QPainter::SmoothPixmapTransform causes artificats even without moving 
anything over the background. If the whole view is repainted due to e.g. 
minimizing and maximazing the window, the artifacts are gone. Is this a 
bug or a fault in my implementation logic?

I'm using Qt 4.6 RC1 on Windows. Here is my simple implementation of a 
tiled QGraphicsScene which is a modification of the proposed "Porting to 
Graphics View - Porting scenes with tiles" from 
http://doc.trolltech.com/4.6-snapshot/graphicsview-porting.html#porting-scenes-with-tiles. 
The constructor is called with a pixmap of different tiles, size of the 
desired grid and the size of one tile in the pixmap.

If you have any optimization tips, please let me know. At least that 
2-dimensional tilesGrid Vector could maybe be a 1-dimensional fixed array.

Thank you for any comments!

  >> Johannes <<


DiagramTileScene::DiagramTileScene(const QPixmap &pixmap, const int 
columns, const int rows,
                                   const int tileWidth, const int 
tileHeight)
                                       : QGraphicsScene(0, 0, (columns * 
tileWidth), (rows * tileHeight))
{
    tilesPixmap = pixmap;
    gridColumns = columns;
    gridRows = rows;
    this->tileWidth = tileWidth;
    this->tileHeight = tileHeight;
    pixmapTileColumns = tilesPixmap.width() / tileWidth;

    tilesGrid.resize(gridRows);
    for (int row = 0; row < gridRows; row++)
        tilesGrid[row].resize(gridColumns);
}

void DiagramTileScene::setCell(const int column, const int row, const 
int tileNumber)
{
    tilesGrid[column][row] = tileNumber;
    update(tileRect(column, row));
}

void DiagramTileScene::fillCells(const int tileNumber)
{
    for (int row = 0; row < gridRows; row++) {
        for (int column = 0; column < gridColumns; column++) {
            tilesGrid[row][column] = tileNumber;
        }
    }
    update();
}

QRect DiagramTileScene::tileRect(const int column, const int row) const
{
    return QRect(column * tileWidth, row * tileHeight, tileWidth, 
tileHeight);
}

QRect DiagramTileScene::tileRect(int tileNumber) const
{
    return tileRect(tileNumber % pixmapTileColumns, tileNumber / 
pixmapTileColumns);
}

void DiagramTileScene::drawBackground(QPainter *painter, const QRectF &rect)
{
    int startColumn = (rect.x() > 0) ? (int) rect.x() / tileWidth : 0;
    int startRow = (rect.y() > 0) ? (int) rect.y() / tileHeight : 0;
    int endColumn = qMin((int) std::ceil(rect.right() / tileWidth), 
gridColumns);
    int endRow = qMin((int) std::ceil(rect.bottom() / tileHeight), 
gridRows);

    for (int row = startRow; row < endRow; row++) {
        for (int column = startColumn; column < endColumn; column++) {
            QRect gridRect = tileRect(column, row);
            painter->drawPixmap(gridRect, tilesPixmap, 
tileRect(tilesGrid[row][column]));
        }
    }
}

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.




More information about the Qt-interest-old mailing list