Problem with SDL_RenderCopy

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
#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
#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:
#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:
#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 GitHub
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?

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.> 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
#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
#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:
#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:
#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 GitHub
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?

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.

[quote:2c17d51c84=“Progers”]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
#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
#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:
#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:
#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 GitHub
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?[/quote:2c17d51c84]
Thanks a lot AlexRou, i was solving this problem about 2 days, but did not know, that the problem is that simple :slight_smile: Thanks again AlexRou :smiley: