Png not rendering

Hi, I’ve started a new project, trying to understand and learn SDL2.
I’ve configurate Clion to work with SDL2 include and library and have no problem with that. I’ve succeed to create a simple window and change the rendering color in it.
Today I’ve tried to improve this in adding a png file on my window, the code built and my window render, but with no image in it…
Here is my code :

#include "Game.h"

SDL_Texture* playerTex;
SDL_Rect srcR, destR;

Game::Game() {

}
Game::~Game() {

}

void Game::init(const char *title, int width, int height, bool fullscreen) {
    int flags = 0;
    if(fullscreen)
        flags=SDL_WINDOW_FULLSCREEN;

    if(SDL_Init(SDL_INIT_EVERYTHING) == 0){
        window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, flags);
        renderer = SDL_CreateRenderer(window, -1, 0);
        if(renderer){
            SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
        }
        isRunning = true;
    }

    SDL_Surface* tmpSurface = IMG_Load("assets/player.png");
    playerTex = SDL_CreateTextureFromSurface(renderer, tmpSurface);
    SDL_FreeSurface(tmpSurface);
}

void Game::handleEvents() {
    SDL_Event event;
    SDL_PollEvent(&event);
    switch(event.type){
        case SDL_QUIT:
            isRunning = false;
            break;
        default:
            break;
    }
}

void Game::update() {
    destR.h = 32;
    destR.w = 32;
}

void Game::render() {
    SDL_RenderClear(renderer);
    SDL_RenderCopy(renderer, playerTex, &destR, &destR);
    SDL_RenderPresent(renderer);
}

void Game::clean() {
    SDL_DestroyWindow(window);
    SDL_DestroyRenderer(renderer);
    SDL_Quit();
}

bool Game::running() {
    return isRunning;
}

I try to put in a variable -> “IMG_Load(“assets/player.png”)” to see if there were an error and it couldent be loaded… but it returns me “0”
I’ve also tried to change my mingw from 64bit to 32 and change the SDL2 library in consequence but same in any setup

Hi there and welcome to the forum!

A couple of errors in your code:

  1. In your render() function, when you render your texture with SDL_RenderCopy(), you’re passing in your destR rect to both the srcrect argument and the dstrect argument.
    You probably want to pass your srcR rect as the srcrect argument and your destR as the dstrect argument.
  2. You don’t initialize you srcR and destR properly, which means that those two SDL_Rect's are containing garbage values, which means their values can be gigantic. Because of this, your texture might be rendered outside of the window’s bounds, with incorrect size values aswell.

Fix the errors above and check if the texture renders correctly.

Many thanks for your help, maybe i’ve forgot to show my main program, I call in my game loop the function update before the render one.
main.cpp :

#include "Game.h"

Game *game = nullptr;

int main( int argc, char* args[] ){

    game = new Game();

    game->init("Title", 800, 600, false);

    while(game->running()){
        game->handleEvents();
        game->update();
        game->render();
    }

    game->clean();

    return 0;
}

But I’ve try your solution. I’ve modified my render() function like this :

void Game::render() {
    SDL_RenderClear(renderer);
    SDL_RenderCopy(renderer, playerTex, &srcR, &destR);
    SDL_RenderPresent(renderer);
}

and I’ve try in two ways the first one was to keep trying in my update function and y set :

void Game::update() {
    srcR.h = 32;
    srcR.w = 32;
    destR.h = 32;
    destR.w = 32;
}

Secondly I’ve initialise those variable in my render function just before de RenderClear.
But none of those are functionning…

I hope I was clear ^^’’

What about the x and y fields in each of the SDL_Rect’s? What do you initialize them to?

In my Game.cpp when i declare them :

SDL_Rect srcR {0, 0}, destR{ 32, 32};

Alright. The next step is to do more debugging. Set out breakpoints in the code and check that the SDL_Surface, the SDL_Texture etc is valid. Each function has a return value so check each of those.

OK, I’ve add two std::cout in my init function

SDL_Surface* tmpSurface = IMG_Load("assets/player.png");
std::cout << tmpSurface;
playerTex = SDL_CreateTextureFromSurface(renderer, tmpSurface);
std::cout << playerTex;
SDL_FreeSurface(tmpSurface);

and both cout return me ‘0’

I’m new to sdl so this might be way over my head. Does Game.h have an include for SDL_Image.h
and are you compiling with the sdl image flag? The sdl_image documentation also has an IMG_INIT(Flags). I did see on another page it as of 1.2(something), its dynamically initialized. Maybe try a hard init?

Heres my source:

from SDL Image Documentation:
Chapter 2: Getting Started62.2 CompilingTo link with SDLimage you should use sdl-config to get the required SDL compilationoptions. After that, compiling with SDLimage is quite easy.Note: Some systems may not have the SDLimage library and include file in the same placeas the SDL library and includes are located, in that case you will need to add more -I and-L paths to these command lines.

Simple Example for compiling an object file:cc -c ‘sdl-config --cflags‘ mysource.cSimple
Example for compiling an object file:cc -o myprogram mysource.o ‘sdl-config --libs‘ -lSDL_image

I’ve already have in my CmakeLists :

target_link_libraries(TestSDL ${SDL2_LIBRARY} ${SDL2_IMAGE_LIBRARY} -lSDL2 -lSDL2_IMAGE)

so i don’t know if I have to add other things

If I’m not wrong, a pointer that returns a value of 0 (false) means that it’s nullptr, which means something failed.

Please add the below code to your code base and try to execute the application. If either the SDL_Surface or the SDL_texture fails to be created, the application breaks in one or both of the functions.

SDL_Surface* pSurface = IMG_Load("assets/player.png");

if(!pSurface)
{
	printf("Failed to load image. Error: %s", IMG_GetError());

	__debugbreak;
}

SDL_Texture* pTexture = SDL_CreateTextureFromSurface(renderer, pSurface);

if(!pTexture)
{
	printf("Failed to create texture. Error: %s", SDL_GetError());

	__debugbreak;
}

I try your code and got this :

Failed to load image. Error: Couldn't open assets/player.pngFailed to create texture. Error: SDL_CreateTextureFromSurface() passed NULL surface

But I don’t understand why he couldn’t open my file :confused:

Here my arborescence
image

So I’ve tried to modifiy my path into the full path from my C: to myproject/assets/player.png and now I’v got no error with your code, but still nothing appear in the screen

Upload your complete code to github or similar and I’ll take a look at it. Don’t forget to include important files to be able to execute the application, like images etc.

1 Like

Here is the link with my full project, maybe you will have to change the link in the FindSDL & FINDSDL2 cmakes to your mingw compiler
Thanks for the time you are taking for me ^^’’

I checked your code and have found the reason why your texture isn’t rendered properly.

The issue is within your srcR rect, in which you’ve set the x and y fields to 50.
The srcrect argument in the SDL_RenderCopy() function expects an SDL_Rect containing information about what portion of the passed in texture to render. The x and y fields tells where on the passed in texture to start the clipping, where (0, 0) is in the upper left corner of the texture, and the w and h fields tells the size of the portion.
In your case, you want to have an SDL_Rect with the fields set to: {0, 0, 32, 32}, telling SDL that you want to render the whole texture, without doing any clipping.

If you would instead have a texture containing two- or more portions (multiple sub-images in one texture, which is often called a spritesheet, spriteset etc), the srcrect would come in handy.
If you, for example, have a texture containing two sub-images placed next to each other, each (32x32) in size, and you want to render them separately, the fields for the two SDL_Rect’s would then be:
{0, 0, 32, 32} and {32, 0, 32, 32}.

When you’ve initialized your srcR correctly, you’ll then see your texture being rendered in the upper left corner of the window.

1 Like

Many thanks for your help ! <3

No worries. Good luck with your project!