'Why isn't my image displaying using SDL2?
I just started coding a game using SDL2 in C, but I quickly ran into a problem : my images are not displayed on the window. I already made the following checks:
- the window and the renderer are successfully created
- my .bmp files are correctly loaded
- the SDL_RenderCopy() function is called, and returns no error
- the SDL_RenderPresent() function is called and returns no error
- I'm not trying to display my images on a 0x0px surface
- my image is a .bmp file
Here is some code, I hope this will help (I'm sorry it's quite disorganized):
Edit: I simplified the showed code
TrapAdventures.c (main file):
#include <SDL2/SDL.h>
#include <stdio.h>
#include "HobbesSDL.h"
#include "TrapInit.h"
#include "TrapKeyboard.h"
#define Ellipsis (return 0)
#define Pass ((void)0)
#define NullKeycode ((SDL_Keycode)0)
int main(void){
HobbesBool TrapRunning = HOBBES_TRUE;
HobbesWindow *TrapWindow;
HobbesRenderer *TrapRenderer;
if (TrapInitContext("Trap adventures", &TrapWindow, &TrapRenderer) != 0){
TrapRunning = HOBBES_FALSE;
}
HobbesSprite *TrapPlayer;
if (TrapInitSprite(&TrapPlayer, TrapRenderer) != 0)
TrapRunning = HOBBES_FALSE;
while (TrapRunning){
if (TrapGetKeyState(TrapKeySpace))//Quit program if spacebar is pressed
TrapRunning = HOBBES_FALSE;
SDL_RenderClear(TrapRenderer);
if (HobbesDisplaySprite(TrapPlayer) != 0){
printf("Error while displaying player!\n");
TrapRunning = HOBBES_FALSE;
}
SDL_RenderPresent(TrapRenderer);
SDL_Delay(50);
}
HobbesDestroySprite(TrapPlayer);
SDL_DestroyRenderer(TrapRenderer);
SDL_DestroyWindow(TrapWindow);
HobbesQuit();
printf("End!\n");
return 0;
}
The HobbesSprite type defined in HobbesSDL.h (my own (and small) library, using SDL2):
typedef struct HobbesSprite {
SDL_Renderer *renderer;
SDL_Surface *surface;
SDL_Texture *texture;
HobbesRect *rect;
HobbesHitbox *hitbox;
HobbesBool hidden;
} HobbesSprite;
Some of the functions in HobbesSDL.c that I use in this code:
#include <SDL2/SDL.h>
#include "HobbesSDL.h"
#include <errno.h>
int HobbesInit(void){
int ret = SDL_Init(SDL_INIT_VIDEO);
if (ret != 0)
fprintf(stderr, "Error while initializing SDL2: %s", SDL_GetError());
return ret;
}
int HobbesDisplaySprite(HobbesSprite *sprite){
if (SDL_RenderCopy(sprite->renderer, sprite->texture, NULL, (SDL_Rect *)sprite->rect) != 0 && !sprite->hidden){
fprintf(stderr, "Error while displaying sprite: %s\n", SDL_GetError());
fclose(stderr);
return -1;
}
return 0;
}
void HobbesUpdateWindow(HobbesRenderer *renderer){
SDL_RenderPresent(renderer);
}
TrapInit.c:
#include <SDL2/SDL.h>
#include "HobbesSDL.h"
#include "TrapInit.h"
/*These first four functions will be used to initialize the rendering context*/
int TrapInitSDL(){
return HobbesInit();
}
HobbesWindow *TrapInitWindow(const char name[]){
SDL_Window *window = SDL_CreateWindow(name, 0, 0, 1000, 1000, 0);
if (window == NULL){
fprintf(stderr, "Error while creating window: %s\n", SDL_GetError());
}
return window;
}
HobbesRenderer *TrapInitRenderer(HobbesWindow *window){
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
if (renderer == NULL){
fprintf(stderr, "Error while creating renderer: %s\n", SDL_GetError());
}
return renderer;
}
int TrapInitContext(const char name[], HobbesWindow **wptr, HobbesRenderer **rptr){
//Initializes the rendering context using the above functions
int InitSDLResult = TrapInitSDL();
*wptr = TrapInitWindow(name);
*rptr = TrapInitRenderer(*wptr);
if (InitSDLResult != 0 || *wptr == NULL || *rptr == NULL)
return 1;
return 0;
}
/*The following function will be used to create every sprite needed in the game*/
int TrapInitSprite(HobbesSprite **Player, HobbesRenderer *renderer){
*Player = HobbesCreateSprite(renderer, "Images/Player.bmp", 0, 724);
if (*Player == NULL)
return 1;
return 0;
}
(I'm sorry that my code is so unclear, but I do my best :) )
My OS is MacOS Big Sur 11.6.4, my graphic card Intel Iris Pro Graphics 6200 1536 Mo, my processor is a 3,3 GHz Intel Core i7 four cores.
Finally, even thought I use the gcc command to compile, my compiler is clang (Apple made the choice to use clang by default, but the command is still gcc…).
If you need any other information, just ask in the comments and I'll answer you the best I can.
Do you have any ideas?
Solution 1:[1]
I did a lot of tests, and finally found the problem.
The problem was that I tried to convert a HobbesRect * to a SDL_Rect *, but I did it wrong. If you look at the code of HobbesDisplaySprite, I do something like this:
SDL_RenderCopy(sprite->renderer, sprite->texture, NULL, (SDL_Rect *)sprite->rect) //(SDL_Rect *)sprite->rect is the problem
I solved my problem using a far more explicit conversion:
SDL_RenderCopy(sprite->renderer, sprite->texture, NULL, &((SDL_Rect){sprite->rect->x, sprite->rect->y, sprite->rect->w, sprite->rect->h}))
Thank you all for your interest in my problem! I'll try to put less code in my question next time ;) !
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Hobbes |
