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.
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?
SDL_RenderPresent
twice with aSDL_RenderClear
in between, is that intentional? \$\endgroup\$