SDL 2.0 - Rendering textures from an array

59 Views Asked by At

I have an array of textures that I want to render in the render loop. When I'm going through the array, I don't get any of the textures actually displayed on the window.

Here's how I'm initializing the textures I wanna use:

SDL_Texture* tracks[5];
SDL_Rect trackRects[5];
for (int i = 1; i < 6; i++) {
    char buf[20];
    snprintf(buf, 20, ".\\assets\\track%d.png", i);
        
    tracks[i-1] = IMG_LoadTexture(appRenderer, buf);
        
    trackRects[i-1].x = 15;
    trackRects[i-1].y = 28*(i-1) + 150;
}

To render all of these, I'm trying to do this:

for (int i = 0; i < 5; i++) {
    res = SDL_RenderCopy(appRenderer, tracks[i], NULL, &trackRects[i]);
    if (res < 0) printError();
}

This does not return any error, and it compiles, but when I start my program it displays none of the images.

Full code:

#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>

int running = 1;
SDL_Window* appWindow = NULL;
SDL_Surface* appSurface = NULL;
SDL_Renderer* appRenderer = NULL;

int res;

int main(int argc, char* argv[]) {
    int videoerror = SDL_Init(SDL_INIT_VIDEO);
    if (videoerror < 0) printError();
    SDL_Window* appWindow = SDL_CreateWindow("name", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1000, 800, SDL_WINDOW_SHOWN);
    
    int imgerror = IMG_Init(IMG_INIT_PNG);
    if (imgerror < 0) printError();
    
    SDL_Renderer* appRenderer = SDL_CreateRenderer(appWindow, -1, SDL_RENDERER_SOFTWARE);
    
    SDL_Texture* tracks[5];
    SDL_Rect trackRects[5];
    for (int i = 1; i < 6; i++) {
        char buf[20];
        snprintf(buf, 20, ".\\assets\\track%d.png", i);
        
        tracks[i-1] = IMG_LoadTexture(appRenderer, buf);
        
        trackRects[i-1].x = 15;
        trackRects[i-1].y = 28*(i-1) + 150;
    }

    while (running == 1) {
        SDL_Event event;
        while (SDL_PollEvent(&event) != 0) {
            if (event.type == SDL_QUIT) {
                running = 0;
            }
        }
        
        SDL_RenderClear(appRenderer);
        
        for (int i = 0; i < 5; i++) {
            res = SDL_RenderCopy(appRenderer, tracks[i], NULL, &trackRects[i]);
            if (res < 0) printError();
        }
        SDL_RenderPresent(appRenderer);
        
        SDL_Delay(100);
    }
    
    SDL_DestroyWindow(appWindow);
    appWindow = NULL;

    IMG_Quit();
    SDL_Quit();
    
    return 0;
}
1

There are 1 best solutions below

0
Craig Estey On BEST ANSWER

Prefaced by my top comments ...

I've added the setup of .w and .h and added a [crude] placement:

#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>

#define WID     1000
#define HGT     800

int running = 1;
SDL_Window *appWindow = NULL;
SDL_Surface *appSurface = NULL;
SDL_Renderer *appRenderer = NULL;

int res;

void
printError(void)
{
    exit(9);
}

int
main(int argc, char *argv[])
{
    int videoerror = SDL_Init(SDL_INIT_VIDEO);

    if (videoerror < 0)
        printError();
    SDL_Window *appWindow = SDL_CreateWindow("name", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WID, HGT, SDL_WINDOW_SHOWN);

    int imgerror = IMG_Init(IMG_INIT_PNG);

    if (imgerror < 0)
        printError();

    SDL_Renderer *appRenderer = SDL_CreateRenderer(appWindow, -1, SDL_RENDERER_SOFTWARE);

    SDL_Texture *tracks[5];
    SDL_Rect trackRects[5];

    int abs_y = 0;
    int abs_x = 0;
    int max_h = 0;

    for (int i = 0; i < 5; i++) {
        char buf[20];

        snprintf(buf, 20, "assets/track%d.png", i + 1);

        SDL_Texture *track = IMG_LoadTexture(appRenderer, buf);
        tracks[i] = track;

        SDL_Rect *rect = &trackRects[i];

        int w;
        int h;
        Uint32 fmt;
        int access;
        SDL_QueryTexture(track,&fmt,&access,&w,&h);

#if 0
        rect->x = 15;
        rect->y = 28 * (i - 1) + 150;

        rect->w = 512;
        rect->h = 512;
#else
        if ((abs_x + w) > WID) {
            abs_x = 0;
            abs_y += max_h;
            max_h = 0;
        }

        rect->x = abs_x;
        rect->y = abs_y;
        rect->w = w;
        rect->h = h;

        abs_x += w;
#endif

        if (h > max_h)
            max_h = h;
    }

    while (running == 1) {
        SDL_Event event;

        while (SDL_PollEvent(&event) != 0) {
            if (event.type == SDL_QUIT) {
                running = 0;
            }
        }

        SDL_RenderClear(appRenderer);

        for (int i = 0; i < 5; i++) {
            res = SDL_RenderCopy(appRenderer, tracks[i], NULL, &trackRects[i]);
            if (res < 0)
                printError();
        }
        SDL_RenderPresent(appRenderer);

        SDL_Delay(100);
    }

    SDL_DestroyWindow(appWindow);
    appWindow = NULL;

    IMG_Quit();
    SDL_Quit();

    return 0;
}

In the code above, I've used cpp conditionals to denote old vs. new code:

#if 0
// old code
#else
// new code
#endif

#if 1
// new code
#endif

Note: this can be cleaned up by running the file through unifdef -k


I used random images on my system. Here is the output: enter image description here