Sprite Animation (Sprite not appearing)

Hi I’m trying to follow this Cheetah Animation I’ve edited the main.cpp to suit my SDL Template on VS 2022, code compiles with no erros but sprite does not appear on the window. For Cheetah.png I used the exact same file path as the Github repo. what’s wrong here?
`#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>
#include <SDL_image.h>
#include “helper.h”

// Definitions
#define TZ_H (512 / 4) // Width of a single frame
#define TZ_V (252 / 2) // Height of a single frame
#define WHITE 255, 255, 255, 255
#define BLACK 0, 0, 0, 255
#define RED 255, 0, 0, 255
#define WW (TZ_H * 2.5)
#define WH (TZ_V * 2.5)
#define FRAME_TIME 0.1f // 100ms per frame

// Globals
int ww = WW;
int wh = WH;

// Visibles
SDL_Surface* temp_surface = NULL;
SDL_Texture* cheetah = NULL;
SDL_Rect cheetah_dst;
SDL_Rect cheetah_src;

// Function prototypes
float time_(void);
void assets_in(void);
void assets_out(void);

// Create a placeholder image if the real one fails to load
SDL_Surface* create_placeholder_surface() {
SDL_Surface* surface = SDL_CreateRGBSurface(0, 512, 252, 32,
0xFF000000,
0x00FF0000,
0x0000FF00,
0x000000FF);
if (surface == NULL) {
printf(“Couldn’t create placeholder surface: %s\n”, SDL_GetError());
return NULL;
}

// Fill with a background color (white)
SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, 255, 255, 255));

// Draw grid lines to represent the sprite frames
for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 2; j++) {
        SDL_Rect frame = { i * 128, j * 126, 128, 126 };
        SDL_FillRect(surface, &frame, SDL_MapRGB(surface->format,50 + i * 40,50 + j * 40,150));

        // Draw a border (white)
        SDL_Rect border = { i * 128 + 5, j * 126 + 5, 118, 116 };
        SDL_FillRect(surface, &border, SDL_MapRGB(surface->format,255, 255, 255));  // White color
    }
}

return surface;

}

// Load assets
void assets_in(void) {
// Try loading the image
temp_surface = IMG_Load(“./assets/gfx/Cheetah.png”);

if (temp_surface == NULL) {
    printf("Failed to load image: %s\n", IMG_GetError());
    printf("Creating placeholder instead\n");

    // Create placeholder
    temp_surface = create_placeholder_surface();
    if (temp_surface == NULL) {
        exit(EXIT_FAILURE);
    }
}
else {
    printf("Image loaded successfully!\n");
}

// Create texture from surface
cheetah = SDL_CreateTextureFromSurface(Renderer, temp_surface);
SDL_FreeSurface(temp_surface);  // Free the surface after creating texture

if (cheetah == NULL) {
    printf("Failed to create texture: %s\n", SDL_GetError());
    exit(EXIT_FAILURE);
}
else {
    printf("Texture created successfully!\n");
}

// Setup destination rectangle (where to draw on screen)
cheetah_dst.w = TZ_H * 2;
cheetah_dst.h = TZ_V * 2;
cheetah_dst.x = ww / 2 - cheetah_dst.w / 2;
cheetah_dst.y = wh / 2 - cheetah_dst.h / 2;

// Setup source rectangle (which part of the sprite sheet to draw)
cheetah_src.w = TZ_H;
cheetah_src.h = TZ_V;
cheetah_src.x = 0;
cheetah_src.y = 0;

printf("Cheetah source rect: x=%d, y=%d, w=%d, h=%d\n", cheetah_src.x, cheetah_src.y, cheetah_src.w, cheetah_src.h);
printf("Cheetah dest rect: x=%d, y=%d, w=%d, h=%d\n", cheetah_dst.x, cheetah_dst.y, cheetah_dst.w, cheetah_dst.h);

}

// Clean up assets
void assets_out(void) {
if (cheetah != NULL) {
SDL_DestroyTexture(cheetah);
cheetah = NULL;
}
}

// Get current time in seconds
float time_(void) {
static Uint64 start = 0;
static float frequency = 0;

if (start == 0) {
    start = SDL_GetPerformanceCounter();
    frequency = (float)SDL_GetPerformanceFrequency();
    return 0.0f;
}

Uint64 counter = SDL_GetPerformanceCounter();
return ((float)(counter - start) / frequency);

}

int main(int argc, char* argv) {
(void)argc;
(void)argv;

// Initialize
init();

// Create a full screen window
Window = SDL_CreateWindow("Cheetah Animation", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP);
if (Window == NULL) {
    printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
    exit(EXIT_FAILURE);
}

// Create renderer
Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_ACCELERATED);
if (Renderer == NULL) {
    printf("Renderer could not be created! SDL_Error: %s\n", SDL_GetError());
    exit(EXIT_FAILURE);
}

// Get the screen dimensions
SDL_DisplayMode displayMode;
if (SDL_GetCurrentDisplayMode(0, &displayMode) != 0) {
    printf("Could not get display mode: %s\n", SDL_GetError());
    exit(EXIT_FAILURE);
}
ww = displayMode.w;
wh = displayMode.h;

printf("Window created in full screen mode: %dx%d\n", ww, wh);

// Load assets
assets_in();

float currentTime = 0.0f;
float accumulator = 0.0f;
SDL_Event event;
int running = 1;

// Main loop
while (running) {
    // Event loop
    while (SDL_PollEvent(&event)) {
        if (event.type == SDL_QUIT) {
            running = 0;
        }
        if (event.type == SDL_KEYDOWN) {
            switch (event.key.keysym.sym) {
            case SDLK_ESCAPE:
                running = 0;
                break;
            default:
                break;
            }
        }
    }

    // Timing and animation
    float newTime = time_();
    float deltaTime = newTime - currentTime;
    currentTime = newTime;
    accumulator += deltaTime;

    if (accumulator >= FRAME_TIME) {
        // Move to the next frame
        cheetah_src.x += TZ_H;

        // If we've reached the end of the row
        if (cheetah_src.x > TZ_H * 3) {
            cheetah_src.x = 0;  // Reset to the start of the row
            // Toggle between top and bottom row
            cheetah_src.y = (cheetah_src.y == 0) ? TZ_V : 0;
        }

        // Reset accumulator, but keep remainder for smoother animation
        accumulator -= FRAME_TIME;
    }

    // Rendering
    SDL_SetRenderDrawColor(Renderer, 0, 0, 255, 255);  // Blue background
    SDL_RenderClear(Renderer);

    if (cheetah == NULL) {
        printf("Cheetah texture is NULL! Skipping render.\n");
    }
    else {
        printf("Rendering cheetah...\n");
        SDL_RenderCopy(Renderer, cheetah, &cheetah_src, &cheetah_dst);
    }

    SDL_RenderPresent(Renderer);

    // Debugging output
    printf("Current time: %f, Delta time: %f, Accumulator: %f\n", currentTime, deltaTime, accumulator);
    printf("Cheetah source rect: x=%d, y=%d, w=%d, h=%d\n", cheetah_src.x, cheetah_src.y, cheetah_src.w, cheetah_src.h);
    printf("Cheetah dest rect: x=%d, y=%d, w=%d, h=%d\n", cheetah_dst.x, cheetah_dst.y, cheetah_dst.w, cheetah_dst.h);
}

// Cleanup
assets_out();
exit_();
return EXIT_SUCCESS;

}`

To make the code appear correctly you should put ``` (on its own line) around it and make sure that any surrounding text is separated by at least one empty line.

```
your code
```

The image rendered fine for me.

Make sure that the image is placed in the correct folder, i.e assets/gfx/.

One thing that got me a bit confused with the code is that two SDL windows and two SDL renderers are being created.

In int main, init() is called, which initializes SDL, creates a window and a renderer, and sets a window icon.
After init() is finished, another window and renderer is created.
So the same SDL_Window* and SDL_Renderer* pointer are set twice. This results in a memory leak, and will probably also cause some strange bugs.

Alright got it, just has to place image in correct folder. Thank You All.