SDL_Renderer не будет отображать текстуры после прохождения функции

У меня небольшая проблема с SDL_Renderer. Я не могу понять, почему это не работает. Давайте посмотрим на этот пример, он отлично работает:

bool running = true;
SDL_Window* window = SDL_CreateWindow("ASDF", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_Texture* texture = IMG_LoadTexture(renderer, "asdf.bmp");
SDL_Event event;

while(running)
{
    while(SDL_PollEvent(&event))
    {
        switch(event.type)
        {
            case SDL_KEYDOWN:
                if(event.key.keysym.sym == SDLK_ESCAPE)
                {
                    running = false;
                }
                break;
            default:
                break;
        }
    }
    SDL_RenderClear(renderer);
    SDL_RenderCopy(renderer, texture, NULL, NULL);
    SDL_RenderPresent(renderer);
}
SDL_DestroyTexture(texture);

Затем дело доходит до классов, и когда я передаю рендерер через функции, он больше не будет работать.

class Sprite
{
public:
    Sprite(const std::string& path) : filePath(path) {};
    ~Sprite() { SDL_DestroyTexture(tex); };
    void draw(SDL_Renderer* renderer);

private:
    const std::string& filePath;
    SDL_Texture* tex;
};

void Sprite::draw(SDL_Renderer* renderer)
{
    printf("renderer sprite = %p\n", renderer);

    tex = IMG_LoadTexture(renderer, filePath.c_str());
    SDL_RenderCopy(renderer, tex, NULL, NULL);
}

int main(int argc, char **argv)
{
    bool running = true;
    SDL_Window* window = SDL_CreateWindow("ASDF", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN);
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    SDL_Event event;

    Sprite* sprite = new Sprite("asdf.bmp");
    while(running)
    {
        printf("renderer main = %p\n", renderer);

        while(SDL_PollEvent(&event))
        {
            switch(event.type)
            {
                case SDL_KEYDOWN:
                    if(event.key.keysym.sym == SDLK_ESCAPE)
                    {
                        running = false;
                    }
                    break;
                default:
                    break;
            }
        }
        SDL_RenderClear(renderer);
        sprite->draw(renderer);
        SDL_RenderPresent(renderer);
    }

    return 0;
}

Адрес рендерера одинаков в main и в функции отрисовки. Я знаю, что я, вероятно, делаю здесь какую-то ошибку новичка, но я не могу ее найти.


person siwers    schedule 04.01.2015    source источник
comment
Не уверен, что это причина, но вы загружаете текстуру снова и снова с каждым вызовом sprite->draw. Вы должны сделать это один раз в конструкторе или функции для загрузки мультимедиа. Возможно, изображение еще не готово к рендерингу, так как оно только что загружено.   -  person Zammalad    schedule 04.01.2015
comment
Спасибо, Заммалад! Это сработало!   -  person siwers    schedule 04.01.2015
comment
Хорошо, тогда я поставлю это как ответ   -  person Zammalad    schedule 05.01.2015


Ответы (1)


Текстура загружается каждый кадр, когда вы вызываете sprite->draw.

Вы должны переместить строку tex = IMG_LoadTexture(renderer, filePath.c_str()); в конструктор, чтобы она загружалась только один раз.

Причина этого в том, что текстура не будет готова к рендерингу в том же кадре, в котором она загружена.

В качестве примечания вы, похоже, не очищаете SDL_Window или SDL_Renderer с их соответствующими функциями уничтожения или вызываете SDL_Quit, хотя я допускаю, что это могло быть опущено для отправки примера кода.

person Zammalad    schedule 05.01.2015