无效的渲染器SDL2

我正在查看代码,我无法找到无效渲染器问题的解决方案。 我是SDL2的初学者,我必须用纯C编写代码。我认为在我的代码中有更多的错误,但由于这个我不能进一步。 代码是波兰语的一半,所以如果你不能得到我可以重写这一点的地方。 在主要我尝试加载function“Odczyt_z_Pliku”时出现问题。 可能某个地方存在问题。 SDL_GetError()表示“无效的渲染器。

#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; } 

当你到达Odczyt_z_PlikuRenderer仍然是一个NULL指针。

就目前而言,在main()函数中,您有一个类型为SDL_Renderer*的变量Renderer (初始化为NULL )。 然后,将该值传递给SDL_Renderer *,它也采用SDL_Renderer*类型的参数。

但是,在C中,这只是指针本身值的副本传递(而不是指针指向的值)。 换句话说,函数的Renderer参数只是在该函数中创建一个局部变量。 所以在Odczyt_z_Pliku你做Renderer = SDL_CreateRenderer(...); 可能会返回一个新指针,但它只将它指定给局部变量Renderer ,但这对main()函数中的Renderer变量没有影响。

在C中,编写一个设置调用函数中作为局部变量的指针值的函数的方法是使用双指针 。 也就是说,将Inicjalizacja的签名Inicjalizacja

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

然后在main() (或其他任何地方)调用它:

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

等等。 (注意:您也使用SDL_Window Okno犯了同样的错误,可能还有其他地方 – 我还没有读完整个代码)。

语法&Okno表示传递变量Okno的地址(即指针)。 由于Okno本身就是一个指针,因此指针的地址是一个双指针

然后在Inicjalizacja写道:

 *Renderer = SDL_CreateRenderer(...); 

Okno*Renderer语法(我觉得有些混乱)表示指针指向的值。 由于此处的Renderer是双指针,这意味着将单个指针 (类型为Renderer* )分配给Renderer*指向的指针。 现在main()函数中的Renderer*指针将被正确初始化。

请注意,您应该将以下检查更改为:

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

等等。 我们知道 Renderer != NULL因为它是指向main()函数中分配的局部变量的指针。 有趣的问题是SDL_CreateRenderer返回的值,因此我们要查看*Renderer