Search code examples
c++imagetexturessdl

SDL2_image rendering not working properly


I am trying to render an image using SDL_image v2.0.0, in SDL2.

I have an image called Red.png in my res/img/ folder. When I try to load the texture, and use SDL_QueryTexture() it gets the size and everything just fine. But when it comes to rendering the actual image, Ive put a rectangle outline to know where the image is, but there is no image in the box.

The class I use to load and render the texture:

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;

};

I know it correctly gets the renderer and loads the image because the DrawRect function works, and if you didn't guess by the name, Red.png is a red rectangle.


Solution

  • Pass nullptr in for srcrect in your SDL_RenderCopy() call:

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

    Right now if x and/or y are larger than image_ SDL will clip srcrect to the extents of image_, end up with an empty rect, and do nothing.

    Example:

    #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 for reference:

    red.png