Search code examples
c++drawingsdl

How can I "freeze" a rendered table?


I have a table that I render like this:

void startRender() {
    this->x = 0;
    this->y = this->bord_y;
    constr_list(coords);
    SDL_SetRenderDrawColor( this->rend, 0x00, 0x00, 0x00, 0xFF );
    for (int i = 0; i < this->cellsInColumn; i++)   {
        for (int j = 0; j < this->cellsInRow; j++)  {
            SDL_Rect outlineRect = { this->x + this->bord_x + (cellWidth*j), this->y+this->bord_y+(cellHeight*i), this->cellWidth, this->cellHeight  };
            SDL_RenderDrawRect( this->rend, &outlineRect );
            comp_in(coords, (this->x + this->bord_x + (cellWidth*j)), (this->y+this->bord_y+(cellHeight*i)));
        }
    }
}

I save the coordinates in a handwritten list for further processing. Furthermore, I tried to display the table in the same place where it was drawn using known coordinates.

void onlyRender() {
    comp* c = coords.head;
    this->x = c->coordX;
    this->y = c->coordY;
    SDL_SetRenderDrawColor( this->rend, 0x00, 0x00, 0x00, 0xFF );
    for (int i = 0; i < this->cellsInColumn; i++)   {
        for (int j = 0; j < this->cellsInRow; j++)  {
            SDL_Rect outlineRect = { this->x, this->y, this->cellWidth, this->cellHeight  };
            SDL_RenderDrawRect( this->rend, &outlineRect );
            if(c->next != NULL) { c = c->next; }
            else{ break; }
            this->x = c->coordX;
        }
        this->y = c->coordY;
    }
}

But the table is displayed below.

startRender() after onlyRender()

Question: Can I make the table always appear in the same place? If so, how?


Solution

  • The root of the problem has been found. If anyone is really interested, here was what happened.

    Referring to this question of mine, when I couldn't draw the grid properly, I missed a very important point. I'm drawing the grid OUTSIDE the main program loop. Here is the code for the current main function:

    int main( int argc, char* args[] ) {
    
        Manager* mainMan = new Manager(1360, 768, 30, 5);
        auto win = mainMan->getWindow();
        mainMan->start();
    
        if( !win.init() )
        {
            cout << "Failed to initialize!" << endl;
        }
        else
        {
            //Main loop flag
            bool quit = false;
    
            //Event handler
            SDL_Event e;
    
            //While application is running
            while( !quit ) {
                mainMan->moveBeam();
                //Handle events on queue
                while( SDL_PollEvent( &e ) != 0 ) {
                    //User requests quit
                    if( e.type == SDL_QUIT )
                    {
                        quit = true;
                    }
                    else if (e.type == SDL_KEYDOWN) {
                        win.handleKeys( e.key );
                    }   
                }
            }
        }
    
        //Free resources and close SDL
        win.close();
    
        return 0;
    }
    

    Function mainMan->start() draws a grid before the main logic of the program. At this point, for some reason, the image is rendered under the "decoration" or under the title bar. It looks like this:

    after mainMan->start()

    But when the program reaches the main loop while( !quit ) everything changes. Now the program considers the first pixel of the window like the (0,0) coordinate, and not some pixel under the title bar. It looks like this:

    after mainMan->moveBeam()

    Maybe somewhere it was said about this feature of the work, but in any case, I found it myself by trial and error. Thank you all for your attention!