Hi everyone, first I must say what a great community! anyways so I recently started with sfml and am self taught in c++ so don't get too technical on me if possible :)
So in my program I have a game class, player class, and graphics class(among others). The program runs fine but I get this error in the console >
An internal OpenGL call failed in Texture.cpp (95) : GL_INVALID_OPERATION, the s
pecified operation is not allowed in the current state
An internal OpenGL call failed in Texture.cpp (95) : GL_INVALID_OPERATION, the s
pecified operation is not allowed in the current state
Process returned 0 (0x0) execution time : 1.947 s
Press any key to continue.
The strange thing is the program seems to run fine. the code just loads up a texture, turns it in to a sprite then draws it to the screen.
Game class...(part of it)
void Game::GameLoop()
{
Graphics graphics;
Player player1;
while (isRunning)
{
player1.Update();
graphics.ClearWindow();
graphics.Draw(player1.xposition,player1.yposition,player1.direction);
graphics.DrawWindow();
//Close out of the window
isRunning = graphics.QueryWindow();
}
graphics.~Graphics();
}
Graphics.h
#ifndef GRAPHICS_H
#define GRAPHICS_H
#include <SFML/Graphics.hpp>
class Graphics
{
public:
Graphics();
~Graphics();
void Load();
void Draw(int xposition,int yposition,char direction);
void DrawWindow();
void ClearWindow();
bool QueryWindow();
sf::RenderWindow window;
sf::Texture chartexture;
sf::Sprite charsprite;
protected:
private:
};
#endif // GRAPHICS_H
Graphics.cpp
#include "Graphics.h"
Graphics::Graphics()
{
window.create(sf::VideoMode(800, 600, 32), "SFML works!");
Load();
}
void Graphics::Load()
{
chartexture.loadFromFile("data/graphics/characters/old man.bmp");
charsprite.setTexture(chartexture);
}
void Graphics::Draw(int xposition,int yposition,char direction)
{
window.draw(charsprite);
}
void Graphics::DrawWindow()
{
window.display();
}
void Graphics::ClearWindow()
{
window.clear(sf::Color::Red);
}
bool Graphics::QueryWindow()
{
sf::Event windowstate;
while (window.pollEvent(windowstate))
{
if(windowstate.type == sf::Event::Closed)return false;
}
return true;
}
Graphics::~Graphics()
{
chartexture.~Texture();
window.close();
}
Any help on how to do away with this would be great. It does't hamper the program but I can see it being problematic down the line...
graphics.~Graphics();
chartexture.~Texture();
This is undefined behavior. Do not call destructors explicitly!
In your example, you need neither call nor define destructors, RAII does everything automatically.
what do I put in it to de-allocate the textures and sprites so I don't cause memory leaks?
You may want to read a basic C++ book and also do a search for RAII, and read the documentation for SFML.
int main()
{
// ...
{
sf::Texture t ;
t.loadFromFile(/**/) ; // resource is loaded.
// ...
} // resource is freed.
{
sf::Texture * t = new sf::Texture ;
t->loadFromFile( /**/ ) ; // resource is loaded.
// ...
delete t ; // resource is freed.
}
{
std::unique_ptr<sf::Texture> t = new sf::Texture ;
t->loadFromFile( /**/ ) ; // resource is loaded.
// ...
} // resource is freed.
}
[Edit: Oops. Missed the cpp tag somehow.]
All my textures are in class headers so I feel like making everything a pointer and having to clean up after it would be a pain in the ***.
Right, that's why you don't do it ;)
A lot of people constantly use new and delete, but this is very bad practice. Especially with C++11, there are almost no cases left where memory must be managed manually. RAII describes the principle that resources (and memory is a resource) can be managed automatically, which is possible because of deterministic destructors. It is basically just that:
void function()
{
sf::Texture t;
...
} // t destroyed when the variable goes out of scope
// sf::Texture uses RAII internally, so it cleans up its own resources
class MyClass
{
sf::Texture t; // t destroyed in the destructor (compiler-generated)
};
In this thread (http://en.sfml-dev.org/forums/index.php?topic=9359), I described the advantages of RAII in details.