Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Manipulating texture file by displaying parts of it without copying
Qt 6.11 is out! See what's new in the release blog

Manipulating texture file by displaying parts of it without copying

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 2 Posters 452 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    Hristo Konstantinov
    wrote on last edited by Hristo Konstantinov
    #1

    So I have this big png file, containing all the elements of the image (I have seen something like this, while browsing the directories of my games as a kid). I want to be able to manipulate this giant texture file, and display parts of it on my custom QGraphicsItem, change their color , paint them one over another, etc. The problem is that if I use copy, the RAM usage ramps up drastically. Currently my code looks something like this (I will try to simplify it a bit):

    class Tooth : public QGraphicsItem
    public:
    
        explicit Tooth(bool (&status)[32], QPixmap &permanent);
        ~Tooth();
    
        QPixmap permanent;
        QPixmap *tooth;
        QRectF bounds;
        QRect toothpaint;
    
        QRectF boundingRect() const override;
    
        void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
    
        virtual void deciduousLogic() = 0;
    protected:
        void keyPressEvent(QKeyEvent *event) override;
    };
    
    class Molar : public Tooth
    {
    public:
    
        Molar(bool (&status)[32], QPixmap &permanent);
    
        void deciduousLogic() override;
    
    };
    
    class Premolar : public Tooth
    {
    public:
    
        QPixmap deciduous;
    
        Premolar(bool (&status)[32] QPixmap& permanent, QPixmap& deciduous);
    
        void deciduousLogic() override;
    };
    
    class Frontal : public Tooth
    {
    public:
    
        QPixmap deciduous;
    
        Frontal(bool (&status)[32], QPixmap& permanent, QPixmap& decidious);
    
        void deciduousLogic() override;
    };
    

    When initializing the items, I pass in their constructors the references of the already loaded textures of the permanent and the deciduous teeth (because teeth on both side of the mouth are mirrored, and there is no point in wasting ram); The status array reference is a boolean array, containing all kinds of diagnoses ( status[0] - permanent or deciduous, status[0] caries on the upper surface, etc.) The deciduousLogic function dictates whether the permenent or the babytooth texture will be painted:

    Molar::Molar(bool (&status)[32], bool (&surfaces)[12], QPixmap &permanent) : Tooth(status, surfaces, permanent) //Molars doesn't have babytooth analogue, so we don't need the deciduous texture;
    {
        bounds.setCoords(0, 0, 54, 150);
    
        tooth = &permanent;
        tooth->scaled(180, 500, Qt::AspectRatioMode::IgnoreAspectRatio);
        toothpaint.setCoords(0, 0, 54, 150);
    }
    
    void Molar::deciduousLogic()
    {
        if(status[0])status[0]=false;
    }
    
    Premolar::Premolar(bool (&status)[32], bool (&surfaces)[12], QPixmap& permanent,  QPixmap& deciduous)
    : Tooth(status, surfaces, permanent), deciduous(deciduous)
    {
        bounds.setCoords(0, 0, 36, 150);
    
        toothpaint.setCoords(0, 0, 36, 150);
    }
    
    void Premolar::deciduousLogic()
    {
        if(!status[0])tooth = &permanent;//.copy(0, 0, 120, 500);
        else tooth = &deciduous;//.copy(0, 0, 120, 500);
    
    }
    
    Frontal::Frontal(bool (&status)[32], bool (&surfaces)[12], QPixmap& permanent,  QPixmap& deciduous)
    : Tooth(status, surfaces, permanent), deciduous(deciduous)
    {
        bounds.setCoords(0, 0, 36, 150);
        tooth = &permanent;
        tooth->scaled(120, 500, Qt::AspectRatioMode::KeepAspectRatioByExpanding);
        toothpaint.setCoords(0, 0, 36, 150);
    }
    
    void Frontal::deciduousLogic()
    {
        if(!status[0])tooth = &permanent;//.copy(0, 0, 120, 500);
        else tooth = &deciduous;//.copy(0, 0, 120, 500);
    }
    

    And finally for the paint function:

    void Tooth::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
    
        deciduousLogic();
        painter->drawPixmap(toothpaint, *tooth);
    
        if (option->state.testFlag(QStyle::State_Selected))
        {
            QColor select = Qt::blue;
            select.setAlphaF(0.1);
            QPen linepen;
            linepen.setColor(Qt::blue);
            linepen.setWidth(1); painter->setPen(linepen);
            painter->drawRect(bounds);
            QBrush selectb(select, Qt::SolidPattern);
            painter->fillRect(bounds, selectb);
        }
    
    }
    

    the whole problem is that my texture files are way bigger. I made a few (containing some sprites of eventual caries that should be drawn on top of the tooth), but scaling doesn't work. It looks something like this: https://imgur.com/a/qJ3ubzC

    The copy method I've commented out works perfectly, but the RAM usage goes double. I don't want to copy, I just want to get references from part of the main texture file and manipulate them, by using CompositionMode, change their coordinates and display them one over another. If QPixmap is not the way to do this, feel free to recommend completely different approach. Thanks in advance!

    Bonus question: The overall size of the textures is approximately 1 mb (They are high res pngs) When I load them to QPixmap, the RAM goes +10 mb. I am completely new to programming and I want to learn how to optimize as much as I can. I know 10mb is not so much nowadays, but to put it perspective, +1000% increase seems alot! Am I using the wrong class to load the textures?

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #2

      Hi
      What about
      https://wiki.qt.io/Loading_Large_Images
      Not 100% sure it can be used for your use case but it worth a read.

      1 Reply Last reply
      3
      • H Offline
        H Offline
        Hristo Konstantinov
        wrote on last edited by
        #3

        At first read, seem like exactly what I need. I will rewrite the code and see if it works :)

        1 Reply Last reply
        2

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved