【问题标题】:SDL2_image rendering not working properlySDL2_image 渲染无法正常工作
【发布时间】:2015-08-26 04:41:53
【问题描述】:

我正在尝试使用 SDL2 中的 SDL_image v2.0.0 渲染图像。

我的 res/img/ 文件夹中有一个名为 Red.png 的图像。当我尝试加载纹理并使用 SDL_QueryTexture() 时,它会获得大小并且一切都很好。但是在渲染实际图像的时候,我放了一个矩形的轮廓来知道图像在哪里,但是框里没有图像。

我用来加载和渲染纹理的类:

class LTexture
{
public:

    ~LTexture()
    {
        SDL_DestroyTexture(image_);
        renderer_ = nullptr;
        image_ = nullptr;
    }

    void init(SDL_Renderer* renderer)
    {
        printf("init texture\n");
        renderer_ = renderer;
    }

    void loadBMP(std::string filename)
    {
        printf("load texture\n");
        image_ = IMG_LoadTexture(renderer_, ("res/img/"+filename).c_str());
        SDL_QueryTexture(image_, NULL, NULL, &imgrect.w, &imgrect.h);
    }

    void render(int x, int y)
    {
        imgrect.x = x;
        imgrect.y = y;
        SDL_SetRenderDrawColor(renderer_, 128, 128, 128, 255);
        if (image_ != nullptr && renderer_ != nullptr)
        {
            printf("%i,  %i\n", imgrect.x, imgrect.y);
            SDL_RenderDrawRect(renderer_, &imgrect);
            SDL_RenderCopy(renderer_, image_, &imgrect, &imgrect);
        }
    }

    bool isLoaded()
    {
        return image_ != nullptr;
    }

private:
    SDL_Renderer* renderer_ = nullptr;
    SDL_Texture* image_ = nullptr;
    SDL_Rect imgrect;

};

我知道它正确地获取了渲染器并加载了图像,因为 DrawRect 函数有效,如果您没有从名称中猜到,Red.png 是一个红色矩形。

【问题讨论】:

    标签: c++ image textures sdl


    【解决方案1】:

    在您的SDL_RenderCopy() 通话中将nullptr 传递给srcrect

    SDL_RenderCopy(renderer_, image_, nullptr, &imgrect);
    

    现在,如果x 和/或y 大于image_,SDL 会将srcrect 剪辑到image_ 的范围内,最终得到一个空矩形,并且什么也不做。

    例子:

    #include <SDL2/SDL.h>
    #include <SDL2/SDL_image.h>
    
    #include <cstdlib>
    #include <string>
    
    class LTexture
    {
    public:
    
        LTexture()
            : renderer_( nullptr )
            , image_( nullptr )
        { }
    
        ~LTexture()
        {
            SDL_DestroyTexture(image_);
            renderer_ = nullptr;
            image_ = nullptr;
        }
    
        void init(SDL_Renderer* renderer)
        {
            printf("init texture\n");
            renderer_ = renderer;
        }
    
        void loadBMP(std::string filename)
        {
            printf("load texture\n");
            image_ = IMG_LoadTexture(renderer_, filename.c_str());
            SDL_QueryTexture(image_, NULL, NULL, &imgrect.w, &imgrect.h);
        }
    
        void render(int x, int y)
        {
            imgrect.x = x;
            imgrect.y = y;
            SDL_SetRenderDrawColor(renderer_, 128, 128, 128, 255);
            if (image_ != nullptr && renderer_ != nullptr)
            {
                printf("%i,  %i\n", imgrect.x, imgrect.y);
                SDL_RenderDrawRect(renderer_, &imgrect);
                SDL_RenderCopy(renderer_, image_, nullptr, &imgrect);
            }
        }
    
        bool isLoaded()
        {
            return image_ != nullptr;
        }
    
    private:
        SDL_Renderer* renderer_;
        SDL_Texture* image_;
        SDL_Rect imgrect;
    };
    
    
    int main( int argc, char** argv )
    {
        SDL_Init( SDL_INIT_EVERYTHING );
        IMG_Init( IMG_INIT_PNG );
    
        SDL_Window * window = SDL_CreateWindow
            (
            "SDL2", 
            SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 
            300, 300, 
            SDL_WINDOW_SHOWN
            );
    
        SDL_Renderer* renderer = SDL_CreateRenderer
            (
            window,
            0,
            SDL_RENDERER_ACCELERATED
            );
    
        LTexture tex;
        tex.init( renderer );
        tex.loadBMP( "red.png" );
    
        bool running = true;
        while( running )
        {
            SDL_Event ev;
            while( SDL_PollEvent( &ev ) )
            {
                if ( ev.type == SDL_QUIT )
                    running = false;
            }
    
            SDL_SetRenderDrawColor( renderer, 0, 0, 0, 255 );
            SDL_RenderFillRect( renderer, NULL );
    
            tex.render( 50, 50 );
    
            SDL_RenderPresent( renderer );
            SDL_Delay( 33 );
        }
    
        SDL_DestroyRenderer( renderer );
        SDL_DestroyWindow( window );
    
        IMG_Quit();
        SDL_Quit();
    
        return 0;
    }
    

    red.png供参考:

    【讨论】:

    • 我用 nullptr 替换了你所说的参数,但它不起作用。我还尝试了 NULL 和 0。我将我的代码与几个在线 src 进行了比较,例如 linklink,但无济于事。这是屏幕外观的图片link
    • @NickM13:我添加了一个可以在我的系统上运行的 MCVE。如果没有 srcrect 更改,我建议我得到与您类似的仅矩形输出。
    【解决方案2】:

    我不知道这是否仍然是实际的,但我在使用 SDL_RENDERER_ACCELERATED 标志(在 Linux Mint 下)时遇到问题,当我使用 SW 加速时,SDL_Render* 可以工作。

    【讨论】: