简体   繁体   中英

SDL_Texture renders black after resize unless it is redrawn

I've got a bit of a nasty bug for you folks. (Yes, it's probably my bug and not SDL's.) I have been in the process of writing a modern C++ wrapper for SDL and everything appears to be working as intended. However, my Texture class has a strange bug: if it is redrawn after a resize, it looks fine, but if it is not, it becomes entirely black. Here is what that looks like:

Before the resize

After the resize

I can't exactly post just one part of the code here, so here is the entire folder (hosted on GitLab): SDL wrapper

Here is a small program that reproduces the error using this library:

#include "sdl_wrapper/context.hh"
#include "sdl_wrapper/video/context.hh"
#include "sdl_wrapper/render/renderer.hh"
#include "sdl_wrapper/render/texture.hh"
#include "sdl_wrapper/colors.hh"
#include "SDL2/SDL_events.h"

int main()
{
    sdl::Context sdlContext;
    sdl::video::Context videoContext = sdlContext.initVideo();
    sdl::video::Window window = videoContext.createWindow("test", 0, 0, 800, 600).resizable().build();
    int width = 800;
    int height = 600;
    sdl::render::Renderer renderer = window.createRenderer().targetTexture().build();
    sdl::render::Texture example(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 400, 300);
    renderer.setTarget(example);
    renderer.setDrawColor(sdl::colors::Blue);
    renderer.clear();
    renderer.resetTarget();
    bool run = true;
    while (run)
    {
        SDL_Event e;
        while (SDL_PollEvent(&e) != 0)
        {
            if (e.type == SDL_QUIT)
            {
                run = false;
                break;
            }
        }
        renderer.setDrawColor({0x44, 0x44, 0x44, 0xff});
        renderer.clear();
        renderer.copy(example, std::nullopt, {{width / 4, height / 4, example.getWidth(), example.getHeight()}});
        renderer.present();
    }
}

To reproduce, simply run this program and resize the window. There will be a blue square that becomes black after the resize.

I would greatly appreciate it if someone could point me in the right direction here. I would really like to avoid redrawing on every resize (feel free to argue with me on that point if I am misguided).

SDL doesn't promise to keep target textures data. There are cases, especially with d3d or mobile, where data is lost due to some big state change. Changing window size may sound not that big, but on some hardware/driver configurations is causes problems, I suppose that's the reason why SDL detects resize and drops all renderer data. You get SDL_RENDER_TARGETS_RESET event when you need to update your render textures.

That shouldn't happen with eg opengl renderer implementation (that may sound great but reasons behind it are not so great); on windows, SDL2 defaults to direct3d, which could be modified by issuing SDL_SetHint or setting envvars.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM