Skip to main content
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
added 1848 characters in body
Source Link
Xriuk
  • 623
  • 9
  • 23

UPDATE:
Ok... Apparently if I remove both SDL_RenderPresent(renderer); the flickering is gone and everything is rendering correctly, but I can't understand why. This is the final function:

void vItem::draw(){
    if(sprites.size() <= 0)
        return;

    // This calculates the dimensions of a rectangle big enough to contain every texture
    SDL_Point size = calculateSpriteRect();

    if(size.x <= 0 || size.y <= 0)
        return;

    // If the final texture does not exists or its dimensions are different from the new rectangle I destroy it and recreate it
    if(final_sprite == NULL || size.x != final_sprite_size.x || size.y != final_sprite_size.y){
        if(final_sprite != NULL)
            SDL_DestroyTexture(final_sprite);
        final_sprite = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, size.x, size.y);
        SDL_SetTextureBlendMode(final_sprite, SDL_BLENDMODE_BLEND);
        final_sprite_size = {size.x, size.y};
    }

    //SDL_RenderPresent(renderer);
    SDL_SetRenderTarget(renderer, final_sprite);
    //SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
    //SDL_RenderClear(renderer);
    for(int i = 0; i < sprites.size(); i++){
        SDL_SetTextureAlphaMod(sprites[i].sprite, sprites[i].alpha);
        SDL_RenderCopy(renderer, sprites[i].sprite, &sprites[i].source, &sprites[i].bounds);
    }   
    //SDL_RenderPresent(renderer);
    SDL_SetRenderTarget(renderer, NULL);
}

How can the renderer keep information about the texture on texture rendering and texture on screen rendering at the same time (since I have only one SDL_RenderPresent() left at the end of my game loop)? Is it meant to work like that?

UPDATE:
Ok... Apparently if I remove both SDL_RenderPresent(renderer); the flickering is gone and everything is rendering correctly, but I can't understand why. This is the final function:

void vItem::draw(){
    if(sprites.size() <= 0)
        return;

    // This calculates the dimensions of a rectangle big enough to contain every texture
    SDL_Point size = calculateSpriteRect();

    if(size.x <= 0 || size.y <= 0)
        return;

    // If the final texture does not exists or its dimensions are different from the new rectangle I destroy it and recreate it
    if(final_sprite == NULL || size.x != final_sprite_size.x || size.y != final_sprite_size.y){
        if(final_sprite != NULL)
            SDL_DestroyTexture(final_sprite);
        final_sprite = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, size.x, size.y);
        SDL_SetTextureBlendMode(final_sprite, SDL_BLENDMODE_BLEND);
        final_sprite_size = {size.x, size.y};
    }

    //SDL_RenderPresent(renderer);
    SDL_SetRenderTarget(renderer, final_sprite);
    //SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
    //SDL_RenderClear(renderer);
    for(int i = 0; i < sprites.size(); i++){
        SDL_SetTextureAlphaMod(sprites[i].sprite, sprites[i].alpha);
        SDL_RenderCopy(renderer, sprites[i].sprite, &sprites[i].source, &sprites[i].bounds);
    }   
    //SDL_RenderPresent(renderer);
    SDL_SetRenderTarget(renderer, NULL);
}

How can the renderer keep information about the texture on texture rendering and texture on screen rendering at the same time (since I have only one SDL_RenderPresent() left at the end of my game loop)? Is it meant to work like that?

Source Link
Xriuk
  • 623
  • 9
  • 23

Render to texture and then to screen cause flickering

So I have my class vItem which has a vector (consider elements like layers) of textures, origin rects and destination rects plus other stuff.
Basically whenever I update any of the layers in the vector I redraw everything on an internal texture which is then displayed on the screen, here's the function that draws on the texture:

void vItem::draw(){
    if(sprites.size() <= 0)
        return;

    // This calculates the dimensions of a rectangle big enough to contain every texture
    SDL_Point size = calculateSpriteRect();

    if(size.x <= 0 || size.y <= 0)
        return;

    // If the final texture does not exists or its dimensions are different from the new rectangle I destroy it and recreate it
    if(final_sprite == NULL || size.x != final_sprite_size.x || size.y != final_sprite_size.y){
        if(final_sprite != NULL)
            SDL_DestroyTexture(final_sprite);
        final_sprite = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, size.x, size.y);
        SDL_SetTextureBlendMode(final_sprite, SDL_BLENDMODE_BLEND);
        final_sprite_size = {size.x, size.y};
    }

    SDL_RenderPresent(renderer);
    SDL_SetRenderTarget(renderer, final_sprite);
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
    SDL_RenderClear(renderer);
    for(int i = 0; i < sprites.size(); i++){
        SDL_SetTextureAlphaMod(sprites[i].sprite, sprites[i].alpha);
        SDL_RenderCopy(renderer, sprites[i].sprite, &sprites[i].source, &sprites[i].bounds);
    }   
    SDL_RenderPresent(renderer);
    SDL_SetRenderTarget(renderer, NULL);
}

The problem comes after this function: I have a child class of vItem called vButton where I have two layers of text (one normal and the other on for when the mouse is over the button), and when I update alpha values of the layers to hide one level and show the other one draw() is called. This transition causes an instant flickering (black background right before drawing).
When I removed vSync I noticed that this wasn't happening anymore, but I need vSync.