the following program runs until SDL_GetRendererInfo is called (in function RenderInit()), and then stops working before SDL_GetError can do anything. replacing global_renderer with a null SDL_Renderer pointer doesn't cause a crash and the expected sdl error is gotten.
#include <iostream>
#include <list>
#include "SDL.h"
using namespace std;
//global variables:
bool run = true; // whether or not the program should be running
int global_window_width = 50; //width of window in tiles
int global_window_height = 35; //height of window in tiles
SDL_Window* global_window = NULL; //points to primary window
SDL_Renderer* global_renderer = NULL; //points to renderer for main window
SDL_RendererInfo* global_renderer_info = NULL; //points to info about above renderer once it's initialized
SDL_Texture* spritesheet = NULL; //holds the spritesheet
SDL_Event event; //for holding currently in-handling event
//function declarations:
int init(); //initialize SDL
int windowInit(); //initialize window
int renderInit(); //create renderers
int viewInit(); //manages all window, rendering, etc stuff
int loadSpritesheet(); //loads spritesheet
void cleanup(); //free up memory, etc
void dispatchEvent(); //main event handling
//function definitions:
int init()
{
if ( SDL_Init(SDL_INIT_EVERYTHING) !=0 )
{
cout << "could not initialize SDL. " << SDL_GetError();
return 1;
}
return 0;
}
int windowInit()
{
global_window = SDL_CreateWindow("roguelike",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
global_window_width * 10,
global_window_height * 10,
SDL_WINDOW_SHOWN);
if(global_window == NULL)
{
cout << "could create window. " << SDL_GetError();
return 1;
}
return 0;
}
int renderInit()
{
global_renderer = SDL_CreateRenderer(global_window,
-1,
SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_ACCELERATED );
if (global_renderer == NULL)
{
cout << "could not create renderer" << SDL_GetError();
return 1;
}
SDL_SetRenderDrawColor(global_renderer,0xFF,0xFF,0xFF,0xFF);
if (SDL_GetRendererInfo(global_renderer, global_renderer_info) != 0)
{
cout << "could not get renderer info" << SDL_GetError();
return 1;
}
return 0;
}
int viewInit()
{
if (windowInit() == 1)
{
return 1;
}
else if(renderInit() == 1)
{
return 1;
}
else if(loadSpritesheet() == 1)
{
return 1;
}
return 0;
}
int loadSpritesheet()
{
SDL_Surface* tempsurf = NULL; //using surface to get image initially, but since surfaces use cpu rendering we switch to textures immediately
tempsurf = SDL_LoadBMP("spritesheet.bmp"); //puts image in the surface
if (tempsurf == NULL)
{
cout << "failed to load spritesheet";
SDL_FreeSurface(tempsurf); //we don't need tempsurf anymore
return 1;
}
spritesheet = SDL_CreateTextureFromSurface(global_renderer, tempsurf);
if (spritesheet == NULL)
{
cout << "failed to create spritesheet texture";
SDL_FreeSurface(tempsurf); //we don't need tempsurf anymore
return 1;
}
SDL_FreeSurface(tempsurf); //we don't need tempsurf anymore
return 0;
}
void cleanup()
{
SDL_DestroyWindow(global_window);
global_window = NULL;
SDL_DestroyRenderer(global_renderer);
global_renderer = NULL;
SDL_DestroyTexture(spritesheet);
spritesheet = NULL;
global_renderer_info = NULL;
SDL_Quit();
}
void dispatchEvent()
{
SDL_PollEvent(&event); //stores current event information
switch(event.type)
{
case SDL_QUIT:
{
run = false;
break;
}
}
}
//classes:
class Layer // each layer holds visuals for a certain subset of what is to be displayed; environment, HUD, menu, etc.
{
Layer(){};
};
class Camera //renders environment, ui, etc in a series of layers
{
int width, height; //in tiles
SDL_Texture* texture_draw; //texture the camera draws to and sends to be displayed
list<Layer*> layer_list; //list of layers to be rendered, back --> front
public:
Camera(int x, int y, SDL_Renderer* renderer): width(x), height(y) //(width, height, renderer for camera to use)
{
texture_draw = SDL_CreateTexture(global_renderer,global_renderer_info->texture_formats[0] , SDL_TEXTUREACCESS_TARGET, 10*width, 10*height);
};
};
//main loop
int main(int argc, char *argv[]) //main function, needed by SDL
{
if(init() == 0)
{
if(viewInit() == 0)
{
while(run)
{
dispatchEvent();
}
}
}
cleanup();
return 0;
}