Need help with my drawBackground function



  • Hey guys,

    this is my first post here and i hope im in the right forum :D

    Currently im working on a level editor for a game that i want to create in the future. Most of it is done but the perfomance is bad. I overrode the drawBackground function from my graphicsscene to draw the tiles:

    @
    int x = 0, y = 0;
    for(int a = 0; a < layers.size(); a++)
    {
    for(auto it : getLayer(a+1)->getTiles())
    {
    painter->drawPixmap(x,y,it->getItem());

                x += tileSizeX;
    
                if(x == tileSizeX*mapSizeX)
                {
                    x = 0;
                    y += tileSizeY;
                }
            }
            y = 0;
        }
    

    @

    The problem is that when i create a map that is 1000x1000 large it is really hard to draw because all layers have to be redrawn. I know this is not the best method but i dont now anything better i tried everything :D

    I hope you guys can help me! :)

    PS: Im a student so my english is not the best but i think you can understand what i wrote :D


  • Moderators

    Hi, welcome to devnet.

    Have you tried... not drawing everything every time? :)
    Draw the tiles once to a pixmap and update them only when a tile changes. There's no need to redraw every tile every frame. Just update the ones that actually change and use the single large pixmap as a background.



  • But how can i do that? If i implement this in the drawbackgrond function it only draws the tile when the function is called and the rest disappear.


  • Moderators

    Sorry, I don't follow. What disappears?

    Usually any game loop looks something like this:

    • Handle user input
    • Process game logic
    • Draw current state
    • Repeat

    So you create a large pixmap before you start anything.
    In the game logic step you check which tiles changed and need to be redrawn. You draw them on the big pixmap in this step.
    In the draw step you just draw the big pixmap as a background instead of each individual tile.
    Another thing - are all 1000x1000 tiles visible at the same time? If not then just update the ones that will actually be visible on the screen.



  • Its hard to describe my problem sorry :D

    My draw code is in the drawbackground function but the problem is that when i just draw one tile there and nothing else the rest of the tiles are not redrawn. So i have to redraw everything because otherwise it isnt showed in the scene.

    But i will try it with a large pixmap, do you have any documentation about drawing on a pixmap? I cant find anything about it.


  • Moderators

    [quote author="Arector" date="1415720419"]But i will try it with a large pixmap, do you have any documentation about drawing on a pixmap? I cant find anything about it.[/quote]

    It's just a matter of creating a painter:
    @
    //create a pixmap and a painter
    QPixmap pixmap(width, height);
    QPainter painter(&pixmap);

    //now you can draw on the pixmap with painter eg.
    painter->drawText(20,30, "Hello"); //draw some text
    painter->drawPixmap(40,50, someTilePixmap); //draw a pixmap
    @



  • Thank you! It isnt working perfectly at the moment but your method works and i think the perfomance should be fine now :)



  • I have one last question ^^ If i draw a 1000x1000 Map now i get this error:

    @QPainter::begin: Paint device returned engine == 0, type: 2@

    I think it comes because Painter tries writing on a null pixmap. When i use a smaller size it works perfectly. Cant qpixmap handle this size?


  • Moderators

    What's the unit of this 1000x1000? Is it in pixels? Or tiles?

    If it's tiles then do the simple math. Assuming a tile is 32x32 and each pixel takes 4 bytes(red, green, blue, alpha) you have this: 1000 * 32 * 1000 * 32 * 4 which is about 4GB of data. If your app is 32bit process then it's waaay beyond the available address space (roughly 2GB per process). On 64bit system you'd get away with it but it's a waste as well.

    I doubt that you're displaying a 4GB worth of data every single frame so you need to plan it better. Divide the space into smaller areas (tiles of tiles) and only keep in memory what is actually showing.

    To be honest a lot of that work Qt can do for you. Take a look at the "40000 Chips example":http://qt-project.org/doc/qt-5/qtwidgets-graphicsview-chip-example.html



  • Okey i wil take a look thanks :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.