通过函数后,SDL_Renderer将不显示纹理 [英] SDL_Renderer won't show textures after passing through the function

查看:177
本文介绍了通过函数后,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和draw函数中相同.我知道我可能在这里犯了一些初学者的错误,但我找不到它.

解决方案

调用sprite->draw时,每帧都将加载纹理.

您应将行tex = IMG_LoadTexture(renderer, filePath.c_str());移至构造函数,以便仅将其加载一次.

这样做的原因是纹理将无法在加载的同一帧中进行渲染.

作为一个旁注,您似乎并没有使用它们各自的destroy函数来清理SDL_WindowSDL_Renderer或调用SDL_Quit,尽管我接受提交代码示例时可能会省略它.

I have a little problem with SDL_Renderer. I can't understand why it doesn't work. Let's look at this example, it works fine:

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);

Then it comes to classes and when I pass the renderer through functions, it won't work anymore.

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;
}

The address of renderer is the same in main and in the draw function. I know that I'm probably making some sort of beginner's mistake here but i can't find it out.

解决方案

The texture is being loaded every frame when you call sprite->draw.

You should move the line tex = IMG_LoadTexture(renderer, filePath.c_str()); to the constructor so that it is only loaded once.

The reason for this is that the texture will not be ready for rendering in the same frame that it is loaded.

As a side note you don't appear to be cleaning up the SDL_Window or SDL_Renderer with their respective destroy functions or calling SDL_Quit although I accept this may have been omitted for submitting the code example.

这篇关于通过函数后,SDL_Renderer将不显示纹理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆