Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: SOLVED! Render window and iterators / vectors  (Read 5494 times)

0 Members and 2 Guests are viewing this topic.

GameBear

  • Jr. Member
  • **
  • Posts: 73
    • View Profile
    • Email
SOLVED! Render window and iterators / vectors
« on: July 20, 2016, 02:56:46 pm »
So. i seem to have a small problem here.

I got a number of Buttons (a class i made) stored in a vector like so:
vector<Buttons> _Btns;

now, all _Btns members have been initialized. each contain a
sf rect
sf text
void render(sf::RenderWindow& l_window)
int update(int x, int y)

and some other functions and variables that are irrelevant to this problem.


now, i update the buttons like so:
Quote
int updated = 0;
for (auto itr = _Btns.begin(); itr != _Btns.end(); ++itr) {
   itr->update(sf::Mouse::getPosition(l_window).x / 2, sf::Mouse::getPosition(l_window).y / 2);
   if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
      updated = itr->TestPress();
      if (updated != 0) current = updated;
   }
}

No problem there.

now, rendering gets a bit odd.

This works:
Quote
_Btns.back().render(l_window);
except that it only lets me render the last button added.

but this:

Quote
for (auto itr = _Btns.begin(); itr != _Btns.end(); ++itr) {
   itr->render(l_window);
}
does not?

neither does:
Quote
_Btns.front().render(l_window);
Now, seeing as i can iterate with the update function, and I can render calling only the "back()"

I'm at a lost... what should i do to iterate and render my _Btns?

//I will get back with the answer if i find it first, but after 12 hours of google search I'm a bit done for!

//i know, the update function is not need in this example, it was just to show that one form works, another does not :S
« Last Edit: July 20, 2016, 08:35:03 pm by GameBear »
string message = "some random dude";
cout << "I'm just " << message;

nicox11

  • Jr. Member
  • **
  • Posts: 51
    • View Profile
Re: Render window and iterators / vectors
« Reply #1 on: July 20, 2016, 03:21:15 pm »
Add more precisions. What do you mean by "doesn't work" ?

You are using a std::vector and a button that hold a texture. Since using push_back from std::vector asume copying the object, do you handle it correctly ? How do you handle texture in general ?

Showing your implementation of the class Button can be usefull for us.

GameBear

  • Jr. Member
  • **
  • Posts: 73
    • View Profile
    • Email
Re: Render window and iterators / vectors
« Reply #2 on: July 20, 2016, 04:51:41 pm »
Add more precisions. What do you mean by "doesn't work" ?

You are using a std::vector and a button that hold a texture. Since using push_back from std::vector asume copying the object, do you handle it correctly ? How do you handle texture in general ?

Showing your implementation of the class Button can be usefull for us.

Of course.

some Detail:
The error i get is:
Quote
Unhandled exception at 0x00147BDE in Platformer.exe: 0xC0000005: Access violation reading location 0x00000259.

added ///COMMENTS ON ERROR

The Code for ButtonTile (the button class) is:

Quote from: ButtonTile.h
#include <SFML\Graphics.hpp>
#include <string>

#pragma once

using namespace std;
class ButtonTile
{
public:
   ButtonTile();
   void init(int x, int y, string Txt, int cmd, sf::Font font);
   ~ButtonTile();

   void update(int x, int y);
   int TestPress();
   void render(sf::RenderWindow& l_window);


private:
   int _x, _y, _xSize, _ySize, _btnCmd;
   string _btnTxt;
   sf::Color _col, _rCol;
   sf::Text _Txt;
   sf::Font _Font;
   sf::RectangleShape _rect;
   bool _hover;
};



Quote from: ButtonTile.cpp
#include "ButtonTile.h"


ButtonTile::ButtonTile()
{
}


ButtonTile::~ButtonTile()
{
}


void ButtonTile::init(int x, int y, string Txt, int cmd, sf::Font font)
{

   _btnTxt = Txt;
   _x = x;
   _y = y;
   _xSize = (_btnTxt.length() * 8 )+3;
   _ySize = 23;
   _btnCmd = cmd;
   _col = sf::Color::Blue;
   _rCol = _col;
   _Font = font;
   _rect.setPosition(sf::Vector2f(_x, _y));
   _rect.setFillColor(_rCol);
   _rect.setSize(sf::Vector2f(_xSize, _ySize));
   _Txt.setFont(_Font);
   _Txt.setColor(sf::Color::White);
   _Txt.setPosition(sf::Vector2f(_x + 3, _y + 3));
   _Txt.setCharacterSize(15);
   _Txt.setString(sf::String(_btnTxt));
   _hover = false;
}

void ButtonTile::update(int x, int y)
{
   if (x > _x && x < _x + _xSize && y > _y && y < _y + _ySize) {
      _rCol = sf::Color::Black;
      _hover = true;
   }
   else {
      _rCol = _col;
      _hover = false;
   }
}

int ButtonTile::TestPress()
{
   if (_hover == true) {
      _rCol = sf::Color::Red;
      return _btnCmd;
   }
   else return 0;
}

void ButtonTile::render(sf::RenderWindow& l_window) {
   _rect.setFillColor(_rCol);
   l_window.draw(_rect);
   l_window.draw(_Txt);
/// <<<---- ACCESS VIALATION POINTS TO THIS END BARAK

And the menu that implements Button tile is:
Quote from: MenuFile.h
#include "ButtonTile.h"
#include <vector>

#pragma once

using namespace std;
class MenuFile
{
public:
   MenuFile();
   ~MenuFile();

   //Update functions, one gets info, other makes it it self.
   // int update(int x, int y, bool clicked, int current); //For later use
   void init(sf::Font font, string l_title);
   
   int update(int current, sf::RenderWindow& l_window);

   void addButton(string Txt, int cmd);

   void render(sf::RenderWindow& l_window);


private:
   int _nBtns;
   sf::RectangleShape _bg;
   vector<ButtonTile> _Btns;
   sf::Text _header;
   sf::Font _font;
};



Quote from: MenuFile.cpp
#include "MenuFile.h"


MenuFile::MenuFile()
{
}


MenuFile::~MenuFile()
{
}


void MenuFile::init(sf::Font font, string l_title) {
   _font = font;
   _header.setFont(_font);
   _header.setString(l_title);
   _header.setPosition(sf::Vector2f(130, 30));
   _header.setColor(sf::Color::White);
   _bg.setFillColor(sf::Color(100,100,130));
   _bg.setSize(sf::Vector2f(350, 90));
   _bg.setPosition(sf::Vector2f(25, 25));
}

int MenuFile::update(int current, sf::RenderWindow& l_window) {
   int updated = 0;
   ///THIS WORKS FINE///
   for (auto itr = _Btns.begin(); itr != _Btns.end(); ++itr) {
      itr->update(sf::Mouse::getPosition(l_window).x / 2, sf::Mouse::getPosition(l_window).y / 2);
      if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
         updated = itr->TestPress();
         if (updated != 0) current = updated;
      }
   }

   return current;
}

void MenuFile::addButton(string Txt, int cmd) {
   _Btns.push_back(ButtonTile());
   _Btns.back().init(100, 70 + (_nBtns * 25), Txt, cmd, _font);
   _nBtns++;
   _bg.setSize(sf::Vector2f(350, 90 + (_nBtns * 25)));
}

void MenuFile::render(sf::RenderWindow& l_window) {
   l_window.draw(_bg);
   l_window.draw(_header);


   ///THIS WORKS FINE///
   _Btns.back().render(l_window);
   
   ///THIS DOES NOT WORK///
   for (auto itr = _Btns.begin(); itr != _Btns.end(); ++itr) {
      itr->render(l_window);
   }
   
}
string message = "some random dude";
cout << "I'm just " << message;

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Render window and iterators / vectors
« Reply #3 on: July 20, 2016, 04:52:39 pm »
Nitpick: "_Btns" is, strictly speaking, not an allowed name. All names beginning with underscore and followed by a upper-case letter (as well as names containing double underscores "__" anywhere) arre reserved for the implementation. That is, only your compiler and standard library are allowed to use such names.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Render window and iterators / vectors
« Reply #4 on: July 20, 2016, 06:05:02 pm »
If that's where the program breaks, it looks like it's the drawing of the sf::Text. I noticed that the actual font resource is stored in the button class. If the vector is re-arranged/re-located, the font is re-located and therefore the text points to the wrong location.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

GameBear

  • Jr. Member
  • **
  • Posts: 73
    • View Profile
    • Email
Re: Render window and iterators / vectors
« Reply #5 on: July 20, 2016, 06:41:36 pm »
Nitpick: "_Btns" is, strictly speaking, not an allowed name. All names beginning with underscore and followed by a upper-case letter (as well as names containing double underscores "__" anywhere) arre reserved for the implementation. That is, only your compiler and standard library are allowed to use such names.

That is true. I've even reminded myself to fix it but forgot...
Thanks its fixed :)


If that's where the program breaks, it looks like it's the drawing of the sf::Text. I noticed that the actual font resource is stored in the button class. If the vector is re-arranged/re-located, the font is re-located and therefore the text points to the wrong location.

Ah, that did seem to be the problem...
the best solution i could find was to update the font each time i render the button, not the most elegant solution, but it works.

Thanks.

Solutions looks like this:

//in the memuFile
Quote
   
for (auto itr = _btns.begin(); itr != _btns.end(); ++itr) {
   itr->render(l_window, _font);
}

//in the button file
Quote
void ButtonTile::render(sf::RenderWindow& l_window, sf::Font& font) {
   _rect.setFillColor(_rCol);
   _txt.setFont(font);
   l_window.draw(_rect);
   l_window.draw(_txt);
}
string message = "some random dude";
cout << "I'm just " << message;

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: SOLVED! Render window and iterators / vectors
« Reply #6 on: July 20, 2016, 08:45:38 pm »
The 'best' solution would be to store the (rather heavy) font resource elsewhere and just store pointers to that resource. This is what sf::Text does already so you can just use that. Just pass the external font to the button when it is created. This also stops a font being loaded separately for every button that uses that font; it should be able to share it.

Glad you managed to get it working though!  :)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

 

anything