I've been trying to draw a label (sf::Text) for a couple hour and my program has been crashing for a reason I can't tell. I used to print a few labels for information output with the same font and within the same class even, but now, it crashes when I draw the sf::Text and ouputs Violation access error.
Can sombebody see my mistake ?
**update, I have found a way to not crash my program, but more problems occur, see lower downClas definition
class Body
{
public:
Body();
Body(RenderWindow&, Color aFillColor, float aRadius, double true_radius, double aMass, Vector2<double> aSpeed, float anOrientation, Vector2<double> aPosition, string aName);
~Body();
CircleShape getCricle();
Derivative initialDerivative(State, double delta_time, vector<Body>);
Derivative nextDerivative(State, Derivative, double delta_time, vector<Body>);
Vector2<double> calc_acceleration(State aState, double delta_time, vector<Body>);
void update(vector<Body> list_of_bodies, double delta_time);
void draw();
bool collide(Body const& aBody);
//GET
string getName();
Vector2<double> getPosition();
float getRadius();
//SET
void setPosition(Vector2f);
//operators
void operator=(Body const& b);
bool operator==(Body const& a);
bool operator>(Body const& a);
private:
RenderWindow& myWin;
CircleShape circle;
string myName;
double mass;
float radius;
Vector2<double> mySpeed;
Vector2<double> position;
Vector2<double> acceleration;
State myState;
double last_chrono;
double true_radius;
double f;
double a;
Font myFont;
Text label;
float orientation;
Color fillColor;
int cpt;
Clock myClock;
Clock utility_clock;
double time;
};
Constructor
Body::Body(RenderWindow &win, Color aFillColor, float aRadius, double t_radius, double aMass, Vector2<double> aSpeed, float anOrientation, Vector2<double> aPosition, string aName)
:myWin(win), fillColor(aFillColor), radius(aRadius), true_radius(t_radius), mySpeed(aSpeed), mass(aMass), orientation(anOrientation), position(aPosition), myName(aName)
{
acceleration = Vector2<double>(0,0);
myState = State(position.x, position.y, mySpeed.x, mySpeed.y);
circle.setPosition(position.x, position.y);
circle.setFillColor(fillColor);
circle.setRadius(true_radius/dist_adjust);
if(!myFont.loadFromFile("ressources/Fonts/arial.ttf")){ //Font loading IS successfull
cout << "problem!!" << endl;
}
label.setFont(myFont);
label.setCharacterSize(12);
label.setColor(Color::Black);
label.setString(myName);
cout << true_radius/dist_adjust << endl;
circle.setOrigin(circle.getLocalBounds().width/2,circle.getLocalBounds().height/2);
last_chrono = 0;
myClock.restart();
}
Draw function
void Body::draw()
{
circle.setRadius(radius);
circle.setPosition(Vector2f(myState.x, myState.y));
myWin.draw(circle);
label.setPosition(myState.x - radius, myState.y - radius - label.getLocalBounds().height);
myWin.draw(label); //THE PROGRAM CRASHES HERE!
}
And for whoever wonders, here is when I call the draw function
for(vector<Body>::iterator it_bodies = myBodies.begin(); it_bodies != myBodies.end(); ++it_bodies){
if(!myPause){
it_bodies->setPosition(Vector2f(it_bodies->getPosition().x - temp_position.x, it_bodies->getPosition().y - temp_position.y));
}
it_bodies->draw();
}
any abvious mistake? Am I victim of the randomly crashing fonts ?
please help!
More testing : I tried to draw the Text in the constructor and the program did not crash :
Body::Body(RenderWindow &win, Color aFillColor, float aRadius, double t_radius, double aMass, Vector2<double> aSpeed, float anOrientation, Vector2<double> aPosition, string aName)
:myWin(win), fillColor(aFillColor), radius(aRadius), true_radius(t_radius), mySpeed(aSpeed), mass(aMass), orientation(anOrientation), position(aPosition), myName(aName)
{
acceleration = Vector2<double>(0,0);
myState = State(position.x, position.y, mySpeed.x, mySpeed.y);
circle.setPosition(position.x, position.y);
circle.setFillColor(fillColor);
circle.setRadius(true_radius/dist_adjust);
if(!myFont.loadFromFile("ressources/Fonts/arial.ttf")){
cout << "problem!!" << endl;
}
label.setFont(myFont);
label.setCharacterSize(12);
label.setColor(Color::Black);
label.setString(myName);
myWin.draw(label); //HERE IS WHERE MY TEXT IS DRAWN
cout << true_radius/dist_adjust << endl;
circle.setOrigin(circle.getLocalBounds().width/2,circle.getLocalBounds().height/2);
last_chrono = 0;
myClock.restart();
}
Further testing brings up more questions : When I comment or uncomment those lines, in the constructor of the Body class, my FPS goes from
70+ when commented to
2 when uncommented. ?!?!? Note that I am not drawing the sf::Text, I am only initiating some of it's attributes. For the record, I only have 9 of these objects, 1 for the sun, and 8 for planets (yes, it is a solar system simulation)
label.setFont(myFont);
label.setCharacterSize(12);
label.setColor(Color::Black);
label.setString(myName);
ok... One last update : I tried setting up the attributes within the draw function instead of the constructor, SURPSIE! my program doesn't crash! Nevertheless, it still drops the FPS drastically. Of course, I would normally not do that because setting atributes multiple times with the same value is a waste of ressources.
void Body::draw()
{
circle.setRadius(radius);
circle.setPosition(Vector2f(myState.x, myState.y));
myWin.draw(circle);
label.setPosition(myState.x - radius, myState.y - radius - label.getLocalBounds().height);
label.setFont(myFont);
label.setCharacterSize(12);
label.setColor(Color::Black);
label.setString(myName);
myWin.draw(label);
}
This is never ending, here is another update... I found one line of code that slows down my program by a lot :
for(vector<Body>::iterator it_bodies = myBodies.begin(); it_bodies != myBodies.end(); ++it_bodies){
if(!myPause){
it_bodies->update(myBodies,delta_time * timing_var); //THIS LINE SUCKS THE JUICE
if(it_bodies->getName() == "Earth"){
temp_position = Vector2<double>(it_bodies->getPosition().x - temp_position.x, it_bodies->getPosition().y - temp_position.y);
}
}
}
you will never guess what is in that function...... COMMENTS!!! yes, only comments.... no actual line of code. Nevertheless, calling that function brings my fps from 1500, down to 700 even if I have only one object in that vector................
Here is the code in case anybody cares :
void Body::update(vector<Body> theBodies, double delta_t)
{
/*
Derivative derivative_a = initialDerivative(myState, delta_t, theBodies);
Derivative derivative_b = nextDerivative(myState, derivative_a, delta_t * 0.5, theBodies);
Derivative derivative_c = nextDerivative(myState, derivative_b, delta_t * 0.5, theBodies);
Derivative derivative_d = nextDerivative(myState, derivative_c, delta_t, theBodies);
double one_over_six = 1.f/6.f;
double dxdt = one_over_six * (derivative_a.vx + 2.f * (derivative_b.vx + derivative_c.vx) + derivative_d.vx);
double dydt = one_over_six * (derivative_a.vy + 2.f * (derivative_b.vy + derivative_c.vy) + derivative_d.vy);
double dvxdt = one_over_six * (derivative_a.ax + 2.f * (derivative_b.ax + derivative_c.ax) + derivative_d.ax);
double dvydt =one_over_six * (derivative_a.ay + 2.f * (derivative_b.ay + derivative_c.ay) + derivative_d.ay);
//UPDATING SPEED AND POSITION (position in pixels, and speed in meters / seconds)
myState.x += dxdt * delta_t / dist_adjust;
myState.y += dydt * delta_t / dist_adjust;
myState.vx += dvxdt * delta_t;
myState.vy += dvydt * delta_t;
*/
/*
if(myName == "Earth"){
stringstream str_a;
stringstream str_g;
stringstream str_r;
stringstream str_f;
stringstream str_speed_x;
stringstream str_speed_y;
stringstream str_speed;
stringstream str_correction_x;
str_g << fixed << setprecision( 20 ) << gravity;
str_f << fixed << setprecision( 20 ) << f;
str_a << fixed << setprecision( 20 ) << a;
str_speed_x << fixed << setprecision( 20 ) << myState.vx;
str_speed_y << fixed << setprecision( 20 ) << myState.vy;
str_speed << fixed << setprecision( 20 ) << sqrt(myState.vy * myState.vy + myState.vx * myState.vx);
Text planete;
planete.setPosition(0,0);
planete.setColor(Color::Black);
planete.setCharacterSize(15);
planete.setFont(font);
planete.setString(" x = " + to_string(myState.x) + ", y = " + to_string(myState.y));
planete.setPosition(0,20);
myWin.draw(planete);
planete.setString("ratio = " + to_string((py - position.y)/(px - position.x)));
planete.setPosition(0,40);
myWin.draw(planete);
planete.setString("delta_time = " + to_string(time_temp));
planete.setPosition(0,60);
myWin.draw(planete);
planete.setString("vitesse x = " + str_speed_x.str());
planete.setPosition(300,0);
myWin.draw(planete);
planete.setString("vitesse y = " + str_speed_y.str());
planete.setPosition(300,20);
myWin.draw(planete);
planete.setString("Vitesse totale = " + str_speed.str());
planete.setPosition(300,40);
myWin.draw(planete);
planete.setString("accélération = " + str_a.str());
planete.setPosition(300,60);
myWin.draw(planete);
planete.setString("distance = " + str_r.str());
planete.setPosition(300,80);
myWin.draw(planete);
planete.setString("force = " + str_f.str());
planete.setPosition(700,0);
myWin.draw(planete);
}*/
}