Renderer non valido SDL2

Sto osservando il codice e non riesco a trovare una soluzione per il problema del renderer non valido. Sono principiante con SDL2 e devo scrivere codice in puro C. Penso che nel mio codice ci siano più errori ma a causa di questo non posso andare oltre. Il codice è metà in un linguaggio polacco, quindi se non riesci a ottenere ciò che è dove posso riscrivere questo un po ‘. Problema si verifica quando in main provo a caricare la funzione “Odczyt_z_Pliku”. Probabilmente da qualche parte c’è un problema. SDL_GetError () dice “renderer non valido.

#include #include #include #pragma warning(disable : 4996) #define WYSOKOSC_EKRANU 768 #define SZEROKOSC_EKRANU 1024 typedef enum bool{ false,true }bool; typedef struct sTekstura { int wysokosc; int szerokosc; SDL_Texture *Tekstura; }sTekstura; void IniTekstury(sTekstura T) { T.wysokosc = 0; T.szerokosc = 0; T.Tekstura = NULL; } void free(sTekstura T) { //Free texture if it exists if (T.Tekstura != NULL) { SDL_DestroyTexture(T.Tekstura); T.Tekstura = NULL; T.szerokosc = 0; T.wysokosc = 0; } } int Odczyt_z_Pliku(char nazwa[50],sTekstura T,SDL_Renderer* Renderer) { free(T); SDL_Texture* nTekstura = NULL; //Load image at specified path SDL_Surface* Powierzchnia = IMG_Load(nazwa); if (Powierzchnia == NULL) { printf("Unable to load image %s! SDL_image Error: %s\n", nazwa, IMG_GetError()); } else { SDL_SetColorKey(Powierzchnia, SDL_TRUE, SDL_MapRGB(Powierzchnia->format, 0xFF, 0xFF, 0xFF)); //Create texture from surface pixels nTekstura = SDL_CreateTextureFromSurface(Renderer, Powierzchnia); if (nTekstura == NULL) { printf("Unable to create texture from %s! SDL Error: %s\n", nazwa, SDL_GetError()); } else { //Get image dimensions T.szerokosc = Powierzchnia->w; T.wysokosc = Powierzchnia->h; } //Get rid of old loaded surface SDL_FreeSurface(Powierzchnia); } //Return success T.Tekstura = nTekstura; if (T.Tekstura != NULL) { return 1; } else { return 0; } } bool Inicjalizacja(SDL_Window *Okno,SDL_Renderer *Renderer) { //Initialization flag bool success = true; //Initialize SDL if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError()); success = false; } else { //Set texture filtering to linear if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1")) { printf("Warning: Linear texture filtering not enabled!"); } //Create window Okno = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SZEROKOSC_EKRANU, WYSOKOSC_EKRANU, SDL_WINDOW_SHOWN); if (Okno == NULL) { printf("Window could not be created! SDL Error: %s\n", SDL_GetError()); success = false; } else { //Create renderer for window Renderer = SDL_CreateRenderer(Okno, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); if (Renderer == NULL) { printf("Renderer could not be created! SDL Error: %s\n", SDL_GetError()); success = false; } else { //Initialize renderer color SDL_SetRenderDrawColor(Renderer, 0xFF, 0xFF, 0xFF, 0xFF); //Initialize PNG loading int imgFlags = IMG_INIT_PNG; if (!(IMG_Init(imgFlags) & imgFlags)) { printf("SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError()); success = false; } } } } return success; } void setBlendMode(sTekstura T, SDL_BlendMode blending) //MK: Funkcja ustawiająca przezroczystosc { //Set blending function SDL_SetTextureBlendMode(T.Tekstura, blending); } void setAlpha(sTekstura T,Uint8 alpha) //MK: Funkcja ustawiająca przezroczystość { //Modulate texture alpha SDL_SetTextureAlphaMod(T.Tekstura, alpha); } void render(int x, int y,sTekstura T,SDL_Renderer *Renderer) { //Set rendering space and render to screen SDL_Rect renderQuad = { x, y, T.szerokosc, T.wysokosc }; SDL_RenderCopy(Renderer, T.Tekstura, NULL, &renderQuad); } int main(int argc, char *argv[]) { SDL_Window * Okno = NULL; SDL_Renderer* Renderer = NULL; sTekstura TloMenu; TloMenu.szerokosc = 0; TloMenu.wysokosc = 0; TloMenu.Tekstura = NULL; sTekstura TloGra; TloGra.szerokosc = 0; TloGra.wysokosc = 0; TloGra.Tekstura = NULL; sTekstura Pudlo; Pudlo.szerokosc = 0; Pudlo.wysokosc = 0; Pudlo.Tekstura = NULL; sTekstura Sciana; Sciana.szerokosc = 0; Sciana.wysokosc = 0; Sciana.Tekstura = NULL; sTekstura StartGry; StartGry.szerokosc = 0; StartGry.wysokosc = 0; StartGry.Tekstura = NULL; sTekstura KoniecGry; KoniecGry.szerokosc = 0; KoniecGry.wysokosc = 0; KoniecGry.Tekstura = NULL; SDL_Event e; //Start up SDL and create window if (!Inicjalizacja(Okno,Renderer)) { printf("Failed to initialize!\n"); } else { if(!Odczyt_z_Pliku("MENU BOMBERMAN.png", Sciana, Renderer)) { puts("Nie wczytano kostki"); return 0; } if (!Odczyt_z_Pliku("pudlo3.bmp", Pudlo, Renderer)) { puts("Nie wczytano pudla"); return 0; } if (!Odczyt_z_Pliku("MenuBomberman.bmp", TloMenu, Renderer)) { puts("Nie wczytano menu"); return 0; } if (!Odczyt_z_Pliku("Mapa.bmp", TloGra, Renderer)) { puts("Nie wczytano mapy"); return 0; } if (!Odczyt_z_Pliku("NEW GAME.bmp", StartGry, Renderer)) { puts("Nie wczytano napisu nowej gry"); return 0; } else { //Set standard alpha blending setBlendMode(StartGry, SDL_BLENDMODE_BLEND); } if (!Odczyt_z_Pliku("exitgimp.bmp", KoniecGry, Renderer)) { puts("Nie wczytano napisu koniec gry"); return 0; } else { //Set standard alpha blending setBlendMode(StartGry, SDL_BLENDMODE_BLEND); } //Main loop flag bool quit = false; //Modulation component Uint8 AlphaStartu = 255; Uint8 AlphaKonca = 127; //While application is running while (!quit) { //Handle events on queue while (SDL_PollEvent(&e) != 0) { //User requests quit if (e.type == SDL_QUIT) { quit = true; } //Handle key presses else if (e.type == SDL_KEYDOWN) { //Increase alpha on w if (e.key.keysym.sym == SDLK_w) { AlphaKonca = 127; AlphaStartu = 255; } //Decrease alpha on s else if (e.key.keysym.sym == SDLK_s) { AlphaKonca = 256; AlphaStartu = 127; } } } //Clear screen SDL_SetRenderDrawColor(Renderer, 0xFF, 0xFF, 0xFF, 0xFF); SDL_RenderClear(Renderer); //Render background render(0, 0, TloMenu, Renderer); //Render front blended setAlpha(KoniecGry,AlphaKonca); setAlpha(StartGry, AlphaStartu); render(0, 0,StartGry,Renderer); render(0, 0,KoniecGry,Renderer); //Update screen SDL_RenderPresent(Renderer); } } //Free resources and close SDL close(); return 0; } 

Quando arrivi a Odczyt_z_Pliku , Renderer è ancora un puntatore NULL .

Così com’è, nella tua funzione main() hai un Renderer variabile di tipo SDL_Renderer* (inizializzato su NULL ). Quindi si passa quel valore NULL in SDL_Renderer * che accetta anche un argomento di tipo SDL_Renderer* .

Tuttavia, in C questo è solo un passaggio di copia del valore del puntatore stesso (non il valore puntato dal puntatore). In altre parole, l’argomento Renderer alla tua funzione crea semplicemente una variabile locale in quella funzione. Quindi in Odczyt_z_Pliku quando fai Renderer = SDL_CreateRenderer(...); questo può restituire un nuovo puntatore ma lo sta solo assegnando alla variabile locale Renderer , ma questo non ha alcun effetto sulla variabile Renderer nella tua funzione main() .

In C, il modo di scrivere una funzione che imposta il valore di un puntatore che è una variabile locale nella funzione chiamante consiste nell’utilizzare un doppio puntatore . Cioè, cambia la firma di Inicjalizacja in

 bool Inicjalizacja(SDL_Window **Okno, SDL_Renderer **Renderer) 

quindi in main() (o altrove) chiamalo come:

 SDL_Window * Okno = NULL; SDL_Renderer* Renderer = NULL; ... if (!Inicjalizacja(&Okno, &Renderer)) { ... } 

e così via. (Nota: hai fatto lo stesso errore con SDL_Window Okno, e possibilmente anche altrove – Non ho letto il codice completo).

La syntax &Okno significa passare l’indirizzo di (cioè un puntatore a) la variabile Okno . Poiché Okno è esso stesso un puntatore, l’indirizzo del puntatore è un doppio puntatore .

Quindi in Inicjalizacja scrivi:

 *Renderer = SDL_CreateRenderer(...); 

e allo stesso modo con Okno . La syntax *Renderer (che trovo alquanto confusa) indica il valore puntato da un puntatore. Poiché Renderer qui è un doppio puntatore, questo significa assegnare il puntatore singolo (di tipo Renderer* ) al puntatore puntato su Renderer . Ora il puntatore Renderer* nella tua funzione main() sarà inizializzato correttamente.

Nota, analogamente dovresti cambiare il seguente controllo per:

 if (*Renderer == NULL) {...} 

e così via. Sappiamo Renderer != NULL poiché è un puntatore a una variabile locale allocata nella nostra funzione main() . La domanda interessante è quale valore restituisce SDL_CreateRenderer , quindi vogliamo guardare *Renderer .