About implementing repeat X for tile objects

I have a question. I have a local version of Tiled that I use for some extra things I want to try. One of these things was changing the behavior of an ImageLayer and repeatX as seen in the pic (mountains at the bottom).

This works but for what I need, I want mapobjects tile its textures when repeatX is clicked (Image circled in red). I have been banging my head against the wall looking for the code that draw’s these images and sets the brush so that Qt::TexturePattern can be enabled / tested. Before I traverse this trail, in Tiled’s current structure, is this even possible? Thanks.

Yes, it’s of course possible, since as you found out the image layers already provide this functionality. :slight_smile:

The trick is in MapRenderer::drawImageLayer, which calls painter->setBrush with the (tinted) image associated with the layer. By setting the image as a brush and then drawing a rectangle, we get a tiled pattern almost for free (this way, it even works when due to zooming out very far, there are a huge amount of instances of the image visible).

1 Like

Thank you for your help!

1 Like

Ugh! After adding the repeatX/Y properties, I think I hit a snag. I don’t think I can support tiling in a vertical or horizontal direction alone. I believe it will tile both directions automatically. I have a feeling I might be wrong and just too new to Qt. :frowning:


What should happen in the other direction then? Stretching the image? I think you can to do that by applying a scale on one axis and limiting the rectangle you’re drawing to the size of the image in the respective dimension.

1 Like

Edit:
I did consider buffered drawing(?), but that seems resource heavy. I could draw to a buffer / painter(??) with excatly what you suggested and then blit (I know :roll_eyes: ) that onto the surface stretching only the dimension that should be stretched.

Stretching is what I figured should be the outcome, but that seems to be more than I need. tiling equally is plenty.

Besides, CallRenderer::render(..) supports so much (beyond objects) and it feels daunting at my current level. :slight_smile:
This feature is really just visual sugar for my map building. I already support it in my game thru GLSL/shaders. I have added very llimited, basic support via:

UPDATE: I’m done for now. This will have to do for personal use. Thanks.

        if (object->isTiling()) {
            bool flippedHorizontally = cell.flippedHorizontally();
            bool flippedVertically = cell.flippedVertically();
            double rotation = 0; // Not sure it's required

            if (cell.flippedAntiDiagonally()) { // Not sure it's required
                rotation = 90;
                flippedHorizontally = flippedVertically;
                flippedVertically = !cell.flippedHorizontally();
            }

            const QTransform oldTransform = painter->transform();
            QTransform transform = oldTransform;

            transform.rotate(rotation);
            transform.translate(flippedHorizontally ? object->width() : 0,
                                flippedVertically ? object->height() : 0);
            transform.scale(flippedHorizontally ? -1 : 1, flippedVertically ? -1 : 1);

            painter->setTransform(transform);
            painter->setBrush(cell.tile()->image());
            painter->setPen(Qt::NoPen);
            painter->drawRect(bounds);
            painter->setTransform(oldTransform);
        } else {
            CellRenderer(painter, this, object->objectGroup()->effectiveTintColor())
                .render(cell, QPointF(), bounds.size());
        }

As seen above, I hard-code the drawing, which seems wrong since you are using fragments to draw onto the surface. This causes complications with full integration into your system which already handles all transformations.

I understand that adding the tiling feature to CallRenderer::render will end up being rather too complicated, and it makes sense to bypass it entirely for rendering tiling tile objects. Good job on getting it done for your own purposes!

1 Like