The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
Problem with SDL_RenderCopy
Progers


Joined: 01 Jul 2014
Posts: 2
Hello!
I have some problems with SDL_RenderCopy so it won't copy anything to the screen, and it's return -1 with SDL_Geterror() invalid texture.
I have some classes in the game, but i will show you just LoadMedia class and Charcter class
In LoadMedia i have LoadSurface function and CreateTexture and PushToContainer function, so i load the surface then i use SDL_CreateTextureFromSurface(Global_Data_LoadMedia::Global_Render,MainSurface); and push the pointer to the vector container.
Then in Charcter i get the texture from the container by LoadTexture function and put it in SDL_RenderCopy arguments, but SDL_RenderCopy returns -1 and invalid texture, i checked all adresses from the begin to the end, and i saw that the texture adress that comes from LoadMedia class is correct.
So now i will give some code here
LoadMedia.h
Code:
#pragma once

#include <string>
#include <vector>

namespace Global_Data_LoadMedia
{
   extern SDL_Renderer* Global_Render;
}

class LoadMedia
{
private:
   //DATA
   std::string Path;
   bool success = true;
   std::vector<SDL_Texture*> Texture_Container;

   //Functions
   void Free();
   void ImageInit();
   void PushTextureToContainer();
   bool LoadSurface();
   bool CreateTexture();
   //SDL
   SDL_Surface* MainSurface = nullptr;
   SDL_Texture* MainTexture = nullptr;
   SDL_Texture* Temp_Texture = nullptr;
   SDL_Renderer* LocalRender = nullptr;
public:
   
   LoadMedia();
   ~LoadMedia();

   void PushTexture(std::string Surface_Path);
   void GetRenderer();
   
   //SDL
   SDL_Texture* Get_Texture(int Texture_Index);
};

LoadMedia.cpp
Code:
#include "stdafx.h"
#include "LoadMedia.h"


LoadMedia::LoadMedia()
{
   
}


LoadMedia::~LoadMedia()
{
   Free();
   Texture_Container.clear();
}

namespace Global_Data_LoadMedia
{
    SDL_Renderer* Global_Render;
}


void LoadMedia::PushTexture(std::string Path_To_Surface)
{
   Path = Path_To_Surface;
   ImageInit();
   if (!LoadSurface())
   {
      std::cerr << "Failed to push texture at LoadSurface" << std::endl;
   }
   else
   {
      if (!CreateTexture())
      {
         std::cerr << "Failed to push texture at CreateTexture" << std::endl;
      }
   }
}

void LoadMedia::ImageInit()
{
   int imgFlags = IMG_INIT_PNG;
   if (!(IMG_Init(imgFlags) & imgFlags))
   {
      std::cerr << "SDL_image could not initialize! SDL_image Error: \n" << IMG_GetError() << std::endl;
   }
   else
   {
      std::cout << "PNG Init Success!" << std::endl;
   }
}

void LoadMedia::PushTextureToContainer()
{
   Texture_Container.push_back(MainTexture);
}

void LoadMedia::Free()
{
   SDL_DestroyTexture(MainTexture);
   SDL_DestroyTexture(Temp_Texture);
   SDL_FreeSurface(MainSurface);

   MainTexture = nullptr;
   Temp_Texture = nullptr;
   MainSurface = nullptr;
}

void LoadMedia::GetRenderer()
{
   LocalRender = Global_Data_LoadMedia::Global_Render;
   if (LocalRender == NULL)
   {
      std::cerr << "ERROR! Could not import MainRender to LocalRender" << std::endl;
   }
}

bool LoadMedia::LoadSurface()
{
   
   MainSurface = IMG_Load(Path.c_str());
   if (MainSurface == NULL)
   {
      std::cerr << "Could not load surface! " << SDL_GetError() << std::endl;
      success = false;
   }
   else
   {
      // SDL_SetColorKey(MainSurface, SDL_TRUE, SDL_MapRGB(MainSurface->format, 0, 0, 0));
   }
   return success;
}

bool LoadMedia::CreateTexture()
{
   GetRenderer();
   MainTexture = SDL_CreateTextureFromSurface(LocalRender, MainSurface);
   if (MainTexture == NULL)
   {
      std::cerr << "Could not create texture from surface! " << SDL_GetError << std::endl;
      success = false;
   }
   else
   {
      PushTextureToContainer();
      Free();
   }
   return success;
}

SDL_Texture* LoadMedia::Get_Texture(int Texture_Index)
{
   Free();
   Temp_Texture = Texture_Container[Texture_Index];
   if (Temp_Texture == NULL)
   {
      std::cerr << "Could not Get_Texture with Index " << Texture_Index << std::endl;
      return NULL;
   }
   else
   {
      return Temp_Texture;
   }
}

Charcter.h:
Code:
#pragma once
#include "GameOBJ.h"
const int Charcter_Height = 28, Charcter_Width = 15;
class Charcter : public GameOBJ
{
private:
   
   SDL_Rect Sprite[LINE][COLUMN];
   SDL_Texture* LoadCharcter(int index);
   void Sprites();

public:
   
   void PushCharcter(std::string Path);
   
   void DrawCharcter(int=0,int=0,int=0);

};


Charcter.cpp:
Code:
#include "stdafx.h"
#include "Charcter.h"

void Charcter::PushCharcter(std::string Path)
{
   LoadTextures.PushTexture(Path);
}

SDL_Texture* Charcter::LoadCharcter(int index)
{
   SDL_Texture* Temp_Texture = GameOBJ::LoadTextures.Get_Texture(index);
   if (Temp_Texture == NULL)
   {
      std::cerr << "No temp_texture at character found " << std::endl;
   }
   else
   {
      return Temp_Texture;
   }
}


void Charcter::DrawCharcter(int x, int y, int rotate)
{
   int check;
   SDL_Rect Dest_Rect;
   Dest_Rect.h = 128;
   Dest_Rect.w = 128;
   Dest_Rect.x = x;
   Dest_Rect.y = y;
   check = SDL_RenderCopy(Global_Data_LoadMedia::Global_Render, LoadCharcter(MainCharcter), NULL, &Dest_Rect);
   std::cout << "Check = " << check << "  " << SDL_GetError() << std::endl;
   
}

For all project code i can give my [url=http://https://github.com/Progerspro/SecondGame_Rewrite/tree/master/SecondGame(Rewrite)]GitHub[/url]
And one other thing, i tried to make MainSurface global for all project, and in Charcter.cpp in SDL_RenderCopy(argument,SDL_CreateTextureFromSurface(Global_Data_LoadMedia::Global_Render,Global_Data_LoadMedia::MainSurface,argument,argument); So it works like that, but i want to give a texture from the container to SDL_RenderCopy arguments, i don't want to make a global surface
So my question is, why when i give SDL_RenderCopy correct texture adress from LoadMedia class it says that the texture is invalid and returns -1? And how to fix this?
Re: Problem with SDL_RenderCopy
AlexRou


Joined: 31 Jan 2014
Posts: 57
bool LoadMedia::CreateTexture()
{
GetRenderer();
MainTexture = SDL_CreateTextureFromSurface(LocalRender, MainSurface);
if (MainTexture == NULL)
{
std::cerr << "Could not create texture from surface! " << SDL_GetError << std::endl;
success = false;
}
else
{
PushTextureToContainer();
Free();
}
return success;
}

void LoadMedia::Free()
{
SDL_DestroyTexture(MainTexture);
SDL_DestroyTexture(Temp_Texture);
SDL_FreeSurface(MainSurface);

MainTexture = nullptr;
Temp_Texture = nullptr;
MainSurface = nullptr;
}

You are basically creating the texture and then destroying it and passing a invalid pointer to the vector.

Progers wrote:
Hello!
I have some problems with SDL_RenderCopy so it won't copy anything to the screen, and it's return -1 with SDL_Geterror() invalid texture.
I have some classes in the game, but i will show you just LoadMedia class and Charcter class
In LoadMedia i have LoadSurface function and CreateTexture and PushToContainer function, so i load the surface then i use SDL_CreateTextureFromSurface(Global_Data_LoadMedia::Global_Render,MainSurface); and push the pointer to the vector container.
Then in Charcter i get the texture from the container by LoadTexture function and put it in SDL_RenderCopy arguments, but SDL_RenderCopy returns -1 and invalid texture, i checked all adresses from the begin to the end, and i saw that the texture adress that comes from LoadMedia class is correct.
So now i will give some code here
LoadMedia.h
Code:
#pragma once

#include <string>
#include <vector>

namespace Global_Data_LoadMedia
{
   extern SDL_Renderer* Global_Render;
}

class LoadMedia
{
private:
   //DATA
   std::string Path;
   bool success = true;
   std::vector<SDL_Texture*> Texture_Container;

   //Functions
   void Free();
   void ImageInit();
   void PushTextureToContainer();
   bool LoadSurface();
   bool CreateTexture();
   //SDL
   SDL_Surface* MainSurface = nullptr;
   SDL_Texture* MainTexture = nullptr;
   SDL_Texture* Temp_Texture = nullptr;
   SDL_Renderer* LocalRender = nullptr;
public:
   
   LoadMedia();
   ~LoadMedia();

   void PushTexture(std::string Surface_Path);
   void GetRenderer();
   
   //SDL
   SDL_Texture* Get_Texture(int Texture_Index);
};

LoadMedia.cpp
Code:
#include "stdafx.h"
#include "LoadMedia.h"


LoadMedia::LoadMedia()
{
   
}


LoadMedia::~LoadMedia()
{
   Free();
   Texture_Container.clear();
}

namespace Global_Data_LoadMedia
{
    SDL_Renderer* Global_Render;
}


void LoadMedia::PushTexture(std::string Path_To_Surface)
{
   Path = Path_To_Surface;
   ImageInit();
   if (!LoadSurface())
   {
      std::cerr << "Failed to push texture at LoadSurface" << std::endl;
   }
   else
   {
      if (!CreateTexture())
      {
         std::cerr << "Failed to push texture at CreateTexture" << std::endl;
      }
   }
}

void LoadMedia::ImageInit()
{
   int imgFlags = IMG_INIT_PNG;
   if (!(IMG_Init(imgFlags) & imgFlags))
   {
      std::cerr << "SDL_image could not initialize! SDL_image Error: \n" << IMG_GetError() << std::endl;
   }
   else
   {
      std::cout << "PNG Init Success!" << std::endl;
   }
}

void LoadMedia::PushTextureToContainer()
{
   Texture_Container.push_back(MainTexture);
}

void LoadMedia::Free()
{
   SDL_DestroyTexture(MainTexture);
   SDL_DestroyTexture(Temp_Texture);
   SDL_FreeSurface(MainSurface);

   MainTexture = nullptr;
   Temp_Texture = nullptr;
   MainSurface = nullptr;
}

void LoadMedia::GetRenderer()
{
   LocalRender = Global_Data_LoadMedia::Global_Render;
   if (LocalRender == NULL)
   {
      std::cerr << "ERROR! Could not import MainRender to LocalRender" << std::endl;
   }
}

bool LoadMedia::LoadSurface()
{
   
   MainSurface = IMG_Load(Path.c_str());
   if (MainSurface == NULL)
   {
      std::cerr << "Could not load surface! " << SDL_GetError() << std::endl;
      success = false;
   }
   else
   {
      // SDL_SetColorKey(MainSurface, SDL_TRUE, SDL_MapRGB(MainSurface->format, 0, 0, 0));
   }
   return success;
}

bool LoadMedia::CreateTexture()
{
   GetRenderer();
   MainTexture = SDL_CreateTextureFromSurface(LocalRender, MainSurface);
   if (MainTexture == NULL)
   {
      std::cerr << "Could not create texture from surface! " << SDL_GetError << std::endl;
      success = false;
   }
   else
   {
      PushTextureToContainer();
      Free();
   }
   return success;
}

SDL_Texture* LoadMedia::Get_Texture(int Texture_Index)
{
   Free();
   Temp_Texture = Texture_Container[Texture_Index];
   if (Temp_Texture == NULL)
   {
      std::cerr << "Could not Get_Texture with Index " << Texture_Index << std::endl;
      return NULL;
   }
   else
   {
      return Temp_Texture;
   }
}

Charcter.h:
Code:
#pragma once
#include "GameOBJ.h"
const int Charcter_Height = 28, Charcter_Width = 15;
class Charcter : public GameOBJ
{
private:
   
   SDL_Rect Sprite[LINE][COLUMN];
   SDL_Texture* LoadCharcter(int index);
   void Sprites();

public:
   
   void PushCharcter(std::string Path);
   
   void DrawCharcter(int=0,int=0,int=0);

};


Charcter.cpp:
Code:
#include "stdafx.h"
#include "Charcter.h"

void Charcter::PushCharcter(std::string Path)
{
   LoadTextures.PushTexture(Path);
}

SDL_Texture* Charcter::LoadCharcter(int index)
{
   SDL_Texture* Temp_Texture = GameOBJ::LoadTextures.Get_Texture(index);
   if (Temp_Texture == NULL)
   {
      std::cerr << "No temp_texture at character found " << std::endl;
   }
   else
   {
      return Temp_Texture;
   }
}


void Charcter::DrawCharcter(int x, int y, int rotate)
{
   int check;
   SDL_Rect Dest_Rect;
   Dest_Rect.h = 128;
   Dest_Rect.w = 128;
   Dest_Rect.x = x;
   Dest_Rect.y = y;
   check = SDL_RenderCopy(Global_Data_LoadMedia::Global_Render, LoadCharcter(MainCharcter), NULL, &Dest_Rect);
   std::cout << "Check = " << check << "  " << SDL_GetError() << std::endl;
   
}

For all project code i can give my [url=http://https://github.com/Progerspro/SecondGame_Rewrite/tree/master/SecondGame(Rewrite)]GitHub[/url]
And one other thing, i tried to make MainSurface global for all project, and in Charcter.cpp in SDL_RenderCopy(argument,SDL_CreateTextureFromSurface(Global_Data_LoadMedia::Global_Render,Global_Data_LoadMedia::MainSurface,argument,argument); So it works like that, but i want to give a texture from the container to SDL_RenderCopy arguments, i don't want to make a global surface
So my question is, why when i give SDL_RenderCopy correct texture adress from LoadMedia class it says that the texture is invalid and returns -1? And how to fix this?
Re: Problem with SDL_RenderCopy
Progers


Joined: 01 Jul 2014
Posts: 2
AlexRou wrote:
bool LoadMedia::CreateTexture()
{
GetRenderer();
MainTexture = SDL_CreateTextureFromSurface(LocalRender, MainSurface);
if (MainTexture == NULL)
{
std::cerr << "Could not create texture from surface! " << SDL_GetError << std::endl;
success = false;
}
else
{
PushTextureToContainer();
Free();
}
return success;
}

void LoadMedia::Free()
{
SDL_DestroyTexture(MainTexture);
SDL_DestroyTexture(Temp_Texture);
SDL_FreeSurface(MainSurface);

MainTexture = nullptr;
Temp_Texture = nullptr;
MainSurface = nullptr;
}

You are basically creating the texture and then destroying it and passing a invalid pointer to the vector.

Progers wrote:
Hello!
I have some problems with SDL_RenderCopy so it won't copy anything to the screen, and it's return -1 with SDL_Geterror() invalid texture.
I have some classes in the game, but i will show you just LoadMedia class and Charcter class
In LoadMedia i have LoadSurface function and CreateTexture and PushToContainer function, so i load the surface then i use SDL_CreateTextureFromSurface(Global_Data_LoadMedia::Global_Render,MainSurface); and push the pointer to the vector container.
Then in Charcter i get the texture from the container by LoadTexture function and put it in SDL_RenderCopy arguments, but SDL_RenderCopy returns -1 and invalid texture, i checked all adresses from the begin to the end, and i saw that the texture adress that comes from LoadMedia class is correct.
So now i will give some code here
LoadMedia.h
Code:
#pragma once

#include <string>
#include <vector>

namespace Global_Data_LoadMedia
{
   extern SDL_Renderer* Global_Render;
}

class LoadMedia
{
private:
   //DATA
   std::string Path;
   bool success = true;
   std::vector<SDL_Texture*> Texture_Container;

   //Functions
   void Free();
   void ImageInit();
   void PushTextureToContainer();
   bool LoadSurface();
   bool CreateTexture();
   //SDL
   SDL_Surface* MainSurface = nullptr;
   SDL_Texture* MainTexture = nullptr;
   SDL_Texture* Temp_Texture = nullptr;
   SDL_Renderer* LocalRender = nullptr;
public:
   
   LoadMedia();
   ~LoadMedia();

   void PushTexture(std::string Surface_Path);
   void GetRenderer();
   
   //SDL
   SDL_Texture* Get_Texture(int Texture_Index);
};

LoadMedia.cpp
Code:
#include "stdafx.h"
#include "LoadMedia.h"


LoadMedia::LoadMedia()
{
   
}


LoadMedia::~LoadMedia()
{
   Free();
   Texture_Container.clear();
}

namespace Global_Data_LoadMedia
{
    SDL_Renderer* Global_Render;
}


void LoadMedia::PushTexture(std::string Path_To_Surface)
{
   Path = Path_To_Surface;
   ImageInit();
   if (!LoadSurface())
   {
      std::cerr << "Failed to push texture at LoadSurface" << std::endl;
   }
   else
   {
      if (!CreateTexture())
      {
         std::cerr << "Failed to push texture at CreateTexture" << std::endl;
      }
   }
}

void LoadMedia::ImageInit()
{
   int imgFlags = IMG_INIT_PNG;
   if (!(IMG_Init(imgFlags) & imgFlags))
   {
      std::cerr << "SDL_image could not initialize! SDL_image Error: \n" << IMG_GetError() << std::endl;
   }
   else
   {
      std::cout << "PNG Init Success!" << std::endl;
   }
}

void LoadMedia::PushTextureToContainer()
{
   Texture_Container.push_back(MainTexture);
}

void LoadMedia::Free()
{
   SDL_DestroyTexture(MainTexture);
   SDL_DestroyTexture(Temp_Texture);
   SDL_FreeSurface(MainSurface);

   MainTexture = nullptr;
   Temp_Texture = nullptr;
   MainSurface = nullptr;
}

void LoadMedia::GetRenderer()
{
   LocalRender = Global_Data_LoadMedia::Global_Render;
   if (LocalRender == NULL)
   {
      std::cerr << "ERROR! Could not import MainRender to LocalRender" << std::endl;
   }
}

bool LoadMedia::LoadSurface()
{
   
   MainSurface = IMG_Load(Path.c_str());
   if (MainSurface == NULL)
   {
      std::cerr << "Could not load surface! " << SDL_GetError() << std::endl;
      success = false;
   }
   else
   {
      // SDL_SetColorKey(MainSurface, SDL_TRUE, SDL_MapRGB(MainSurface->format, 0, 0, 0));
   }
   return success;
}

bool LoadMedia::CreateTexture()
{
   GetRenderer();
   MainTexture = SDL_CreateTextureFromSurface(LocalRender, MainSurface);
   if (MainTexture == NULL)
   {
      std::cerr << "Could not create texture from surface! " << SDL_GetError << std::endl;
      success = false;
   }
   else
   {
      PushTextureToContainer();
      Free();
   }
   return success;
}

SDL_Texture* LoadMedia::Get_Texture(int Texture_Index)
{
   Free();
   Temp_Texture = Texture_Container[Texture_Index];
   if (Temp_Texture == NULL)
   {
      std::cerr << "Could not Get_Texture with Index " << Texture_Index << std::endl;
      return NULL;
   }
   else
   {
      return Temp_Texture;
   }
}

Charcter.h:
Code:
#pragma once
#include "GameOBJ.h"
const int Charcter_Height = 28, Charcter_Width = 15;
class Charcter : public GameOBJ
{
private:
   
   SDL_Rect Sprite[LINE][COLUMN];
   SDL_Texture* LoadCharcter(int index);
   void Sprites();

public:
   
   void PushCharcter(std::string Path);
   
   void DrawCharcter(int=0,int=0,int=0);

};


Charcter.cpp:
Code:
#include "stdafx.h"
#include "Charcter.h"

void Charcter::PushCharcter(std::string Path)
{
   LoadTextures.PushTexture(Path);
}

SDL_Texture* Charcter::LoadCharcter(int index)
{
   SDL_Texture* Temp_Texture = GameOBJ::LoadTextures.Get_Texture(index);
   if (Temp_Texture == NULL)
   {
      std::cerr << "No temp_texture at character found " << std::endl;
   }
   else
   {
      return Temp_Texture;
   }
}


void Charcter::DrawCharcter(int x, int y, int rotate)
{
   int check;
   SDL_Rect Dest_Rect;
   Dest_Rect.h = 128;
   Dest_Rect.w = 128;
   Dest_Rect.x = x;
   Dest_Rect.y = y;
   check = SDL_RenderCopy(Global_Data_LoadMedia::Global_Render, LoadCharcter(MainCharcter), NULL, &Dest_Rect);
   std::cout << "Check = " << check << "  " << SDL_GetError() << std::endl;
   
}

For all project code i can give my [url=http://https://github.com/Progerspro/SecondGame_Rewrite/tree/master/SecondGame(Rewrite)]GitHub[/url]
And one other thing, i tried to make MainSurface global for all project, and in Charcter.cpp in SDL_RenderCopy(argument,SDL_CreateTextureFromSurface(Global_Data_LoadMedia::Global_Render,Global_Data_LoadMedia::MainSurface,argument,argument); So it works like that, but i want to give a texture from the container to SDL_RenderCopy arguments, i don't want to make a global surface
So my question is, why when i give SDL_RenderCopy correct texture adress from LoadMedia class it says that the texture is invalid and returns -1? And how to fix this?

Thanks a lot AlexRou, i was solving this problem about 2 days, but did not know, that the problem is that simple Smile Thanks again AlexRou Very Happy