title: SDL 2.0 - Invalid Renderer Error
body: <p>I have just gotten too frustrated with trying to figure this out. I have been following <a href="http://lazyfoo.net/tutorials/SDL/index.php" rel="nofollow noreferrer">http://lazyfoo.net/tutorials/SDL/index.php</a>. I then tried to start making a game with SDL2 but ran into this error very quickly: I can't render anything to the screen. The screen pops up, and I can clear it correctly and everything. If I call SDL_GetError(), the output is "Invalid Renderer". I've checked the code to try to find out where this error could be caused, and searched the internet to no avail. Something that might be causing the problem is that I have a class which has a render method. This render method calls a render method on its texture. That might be the place where I screwed up somehow, but I can't tell.</p>
  
  <p>Source code:</p>
  
  <pre><code>#include &lt;SDL2/SDL.h&gt;
  #include &lt;SDL2/SDL_image.h&gt;
  #include &lt;string&gt;
  #include &lt;stdio.h&gt;
  
  const int WINDOW_WIDTH = 1280;
  const int WINDOW_HEIGHT= 960;
  
  SDL_Window* gWindow = NULL;
  SDL_Renderer* gRenderer = NULL;
  
  enum MOVEMENT_STATES
  {
      DOWN1,
      DOWN2,
      LEFT1,
      LEFT2,
      RIGHT1,
      RIGHT2,
      UP1,
      UP2,
      MOVEMENT_STATES_TOTAL
  };
  
  //Texture wrapper class
  class LTexture
  {
      public:
  
          //Initializes variables
          LTexture(std::string path);
  
          //Deallocates memory
          ~LTexture();
  
          #ifdef _SDL_TTF_H
          //Creates image from font string
          bool loadFromRenderedText( std::string textureText, SDL_Color textColor );
          #endif
  
          //Deallocates texture
          void free();
  
          //Set color modulation
          void setColor( Uint8 red, Uint8 green, Uint8 blue );
  
          //Set blending
          void setBlendMode( SDL_BlendMode blending );
  
          //Set alpha modulation
          void setAlpha( Uint8 alpha );
  
          //Renders texture at given point
          void render( int x, int y, SDL_Rect* clip = NULL, double angle = 0.0, SDL_Point* center = NULL, SDL_RendererFlip flip = SDL_FLIP_NONE );
  
          //Gets image dimensions
          int getWidth();
          int getHeight();
  
      private:
  
          //Loads image at specified path
          bool loadFromFile( std::string path );
  
          //The actual hardware texture
          SDL_Texture* mTexture;
  
          //Image dimensions
          int mWidth;
          int mHeight;
  };
  
  //Sprite classes
  class Entity
  {
      public:
  
          Entity(int hp);
  
          ~Entity();
  
          //void handleEntity(); Unimplemented
  
          void render(int x, int y);
  
          int health;
          int maxHealth;
  
          LTexture* mCurrentTexture;
  };
  
  Entity::Entity(int hp)
  {
      mCurrentTexture = NULL;
  
      health = hp;
      maxHealth = hp;
  }
  
  Entity::~Entity()
  {
      mCurrentTexture = NULL;
  }
  
  void Entity::render(int x, int y)
  {
      //If current texture is non-null, render it
      if (mCurrentTexture != NULL)
      {
          (*mCurrentTexture).render(x, y);
      }
      else
      {
          printf("Texture is null!\n");
      }
  }
  
  LTexture::LTexture(std::string path)
  {
      //Initialize
      mTexture = NULL;
      loadFromFile(path);
      mWidth = 0;
      mHeight = 0;
  }
  
  LTexture::~LTexture()
  {
      //Deallocate
      free();
  }
  
  bool LTexture::loadFromFile( std::string path )
  {
      //Get rid of preexisting texture
      free();
  
      //The final texture
      SDL_Texture* newTexture = NULL;
  
      //Load image at specified path
      SDL_Surface* loadedSurface = IMG_Load( path.c_str() );
      if( loadedSurface == NULL )
      {
          printf( "Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError() );
      }
      else
      {
          //Color key image
          SDL_SetColorKey( loadedSurface, SDL_TRUE, SDL_MapRGB( loadedSurface-&gt;format, 0, 0xFF, 0xFF ) );
  
          //Create texture from surface pixels
          newTexture = SDL_CreateTextureFromSurface( gRenderer, loadedSurface );
          if( newTexture == NULL )
          {
              printf( "Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError() );
          }
          else
          {
              //Get image dimensions
              mWidth = loadedSurface-&gt;w;
              mHeight = loadedSurface-&gt;h;
          }
  
          //Get rid of old loaded surface
          SDL_FreeSurface( loadedSurface );
      }
  
      //Return success
      mTexture = newTexture;
      return mTexture != NULL;
  }
  
  #ifdef _SDL_TTF_H
  bool LTexture::loadFromRenderedText( std::string textureText, SDL_Color textColor )
  {
      //Get rid of preexisting texture
      free();
  
      //Render text surface
      SDL_Surface* textSurface = TTF_RenderText_Solid( gFont, textureText.c_str(), textColor );
      if( textSurface != NULL )
      {
          //Create texture from surface pixels
          mTexture = SDL_CreateTextureFromSurface( gRenderer, textSurface );
          if( mTexture == NULL )
          {
              printf( "Unable to create texture from rendered text! SDL Error: %s\n", SDL_GetError() );
          }
          else
          {
              //Get image dimensions
              mWidth = textSurface-&gt;w;
              mHeight = textSurface-&gt;h;
          }
  
          //Get rid of old surface
          SDL_FreeSurface( textSurface );
      }
      else
      {
          printf( "Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError() );
      }
  
  
      //Return success
      return mTexture != NULL;
  }
  #endif
  
  void LTexture::free()
  {
      //Free texture if it exists
      if( mTexture != NULL )
      {
          SDL_DestroyTexture( mTexture );
          mTexture = NULL;
          mWidth = 0;
          mHeight = 0;
      }
  }
  
  void LTexture::setColor( Uint8 red, Uint8 green, Uint8 blue )
  {
      //Modulate texture rgb
      SDL_SetTextureColorMod( mTexture, red, green, blue );
  }
  
  void LTexture::setBlendMode( SDL_BlendMode blending )
  {
      //Set blending function
      SDL_SetTextureBlendMode( mTexture, blending );
  }
  
  void LTexture::setAlpha( Uint8 alpha )
  {
      //Modulate texture alpha
      SDL_SetTextureAlphaMod( mTexture, alpha );
  }
  
  void LTexture::render( int x, int y, SDL_Rect* clip, double angle, SDL_Point* center, SDL_RendererFlip flip )
  {
      //Set rendering space and render to screen
      SDL_Rect renderQuad = { x, y, mWidth, mHeight };
  
      //Set clip rendering dimensions
      if( clip != NULL )
      {
          renderQuad.w = clip-&gt;w;
          renderQuad.h = clip-&gt;h;
      }
  
      //Render to screen
      SDL_RenderCopyEx( gRenderer, mTexture, clip, &amp;renderQuad, angle, center, flip );
  }
  
  int LTexture::getWidth()
  {
      return mWidth;
  }
  
  int LTexture::getHeight()
  {
      return mHeight;
  }
  
  bool init()
  {
      bool success = true;
  
      //Initialize SDL
      if(SDL_Init(SDL_INIT_VIDEO) &lt; 0)
      {
          printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
          success = false;
      }
      else
      {
          //Enable VSync
          if(!SDL_SetHint(SDL_HINT_RENDER_VSYNC, "1"))
          {
              printf("Warning: VSync not enabled!");
          }
          //Set texture filtering to linear
          if( !SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "1" ) )
          {
              printf( "Warning: Linear texture filtering not enabled!" );
          }
      }
  
      //Create window
      gWindow = SDL_CreateWindow("Dungeon Dash", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
      if (gWindow == NULL)
      {
          printf("SDL could not create window! SDL Error: %s\n", SDL_GetError());
          success = false;
      }
      else
      {
          //Create renderer for window
          gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED);
          if (gRenderer == NULL)
          {
              printf("SDL could not create renderer! SDL Error: %s\n", SDL_GetError());
              success = false;
          }
          else
          {
              //Initialize renderer color
              SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
  
              //Initialize PNG loading
              int imgFlags = IMG_INIT_PNG;
              if( !( IMG_Init( imgFlags ) &amp; imgFlags ) )
              {
                  printf( "SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError() );
                  success = false;
              }
          }
      }
  
      return success;
  }
  
  int main(int argc, char* args[])
  {
  
      if(!init())
      {
          printf("SDL could not initialize!\n");
      }
      else
      {
  
          bool quit = false;
          SDL_Event e; //Event handler
  
          //Load all textures
          LTexture boltTexture("graphics/bolt.png");
          LTexture burst1Texture("graphics/burst1.png");
          LTexture burst2Texture("graphics/burst2.png");
          LTexture chestTexture("graphics/chest.png");
          LTexture coinTexture("graphics/coin.png");
          LTexture emptyTileTexture("graphics/emptyTile.png");
          LTexture floorTileTexture("graphics/floorTile.png");
          LTexture healthPadTexture("graphics/healthPad.png");
          LTexture keyTexture("graphics/key.png");
          LTexture snakeDown1Texture("graphics/snakeDown1.png");
          LTexture snakeDown2Texture("graphics/snakeDown2.png");
          LTexture snakeLeft1Texture("graphics/snakeLeft1.png");
          LTexture snakeLeft2Texture("graphics/snakeLeft2.png");
          LTexture snakeRight1Texture("graphics/snakeRight1.png");
          LTexture snakeRight2Texture("graphics/snakeRight2.png");
          LTexture snakeUp1Texture("graphics/snakeUp1.png");
          LTexture snakeUp2Texture("graphics/snakeUp2.png");
          LTexture spiderDown1Texture("graphics/spiderDown1.png");
          LTexture spiderDown2Texture("graphics/spiderDown2.png");
          LTexture spiderLeft1Texture("graphics/spiderLeft1.png");
          LTexture spiderLeft2Texture("graphics/spiderLeft2.png");
          LTexture spiderRight1Texture("graphics/spiderRight1.png");
          LTexture spiderRight2Texture("graphics/spiderRight2.png");
          LTexture spiderUp1Texture("graphics/spiderUp1.png");
          LTexture spiderUp2Texture("graphics/spiderUp2.png");
          LTexture teleportPadTexture("graphics/teleportPad.png");
          LTexture upgradePadTexture("graphics/upgradePad.png");
          LTexture wallTileDownTexture("graphics/wallTileDown.png");
          LTexture wallTileLeftTexture("graphics/wallTileLeft.png");
          LTexture wallTileRightTexture("graphics/wallTileRight.png");
          LTexture wallTileUpTexture("graphics/wallTileUp.png");
          LTexture wizardDown1Texture("graphics/wizardDown1.png");
          LTexture wizardDown2Texture("graphics/wizardDown2.png");
          LTexture wizardLeft1Texture("graphics/wizardLeft1.png");
          LTexture wizardLeft2Texture("graphics/wizardLeft2.png");
          LTexture wizardRight1Texture("graphics/wizardRight1.png");
          LTexture wizardRight2Texture("graphics/wizardRight2.png");
          LTexture wizardUp1Texture("graphics/wizardUp1.png");
          LTexture wizardUp2Texture("graphics/wizardUp2.png");
  
          //Main player
          Entity player1(20);
          player1.mCurrentTexture = &amp;wizardDown1Texture;
  
          //Main loop
          while(!quit)
          {
              //Event loop
              while(SDL_PollEvent(&amp;e) != 0)
              {
                  if(e.type == SDL_QUIT)
                  {
                      quit = true;
                  }
              }
  
              //Clear screen
              SDL_SetRenderDrawColor(gRenderer, 0, 0, 0, 255);
              SDL_RenderClear(gRenderer);
  
              player1.render(0, 0);
  
              //Update screen
              SDL_RenderPresent(gRenderer);
          }
  
          //If script reaches here, user has exited; quit program
  
          //Free loaded images
          boltTexture.free();
          burst1Texture.free();
          burst2Texture.free();
          chestTexture.free();
          coinTexture.free();
          emptyTileTexture.free();
          floorTileTexture.free();
          healthPadTexture.free();
          keyTexture.free();
          snakeDown1Texture.free();
          snakeDown2Texture.free();
          snakeLeft1Texture.free();
          snakeLeft2Texture.free();
          snakeRight1Texture.free();
          snakeRight2Texture.free();
          snakeUp1Texture.free();
          snakeUp2Texture.free();
          spiderDown1Texture.free();
          spiderDown2Texture.free();
          spiderLeft1Texture.free();
          spiderLeft2Texture.free();
          spiderRight1Texture.free();
          spiderRight2Texture.free();
          spiderUp1Texture.free();
          spiderUp2Texture.free();
          teleportPadTexture.free();
          upgradePadTexture.free();
          wallTileDownTexture.free();
          wallTileLeftTexture.free();
          wallTileRightTexture.free();
          wallTileUpTexture.free();
          wizardDown1Texture.free();
          wizardDown2Texture.free();
          wizardLeft1Texture.free();
          wizardLeft2Texture.free();
          wizardRight1Texture.free();
          wizardRight2Texture.free();
          wizardUp1Texture.free();
          wizardUp2Texture.free();
  
          //Destroy window
          SDL_DestroyRenderer( gRenderer );
          SDL_DestroyWindow( gWindow );
          gWindow = NULL;
          gRenderer = NULL;
  
          //Quit SDL subsystems
          IMG_Quit();
          SDL_Quit();
      }
  }
  </code></pre>
  
  <p>Thanks in advance for any help.</p>