Vector of class not storing separate Textures - c++

I'm creating a car simulation using SFML.
As a matter of organization and logic, I created a single class "car", which also inherits sf::RectangleShape, and within this class there are other SFML objects, among them a Texture and a method to setup it.
I want to have multiple cars, so I created a vector of class "car".
In this example, I left only 2 cars with the images:
"car-red.png" and "car-black.png".
Here is an extract from the logic I'm using (I did a test program to make it easier to understand):
#include <iostream>
#include <vector>
#include <SFML/Graphics.hpp>
#define debug(x) std::cout << #x << "=" << x << std::endl;
using namespace std;
class car : public sf::RectangleShape {
public:
string s;
sf::Texture tex;
sf::Sprite img;
void imgInit(string imgFile) {
tex.loadFromFile(imgFile);
img.setTexture(tex);
s = imgFile;
}
};
int main()
{
vector<car> vecRet;
car objRet;
objRet.imgInit("car-red.png");
objRet.setSize(sf::Vector2f(150, 70));
objRet.setFillColor(sf::Color::Yellow);
vecRet.push_back(objRet);
objRet.imgInit("car-black.png");
objRet.setPosition(sf::Vector2f(300, 300));
objRet.img.setPosition(objRet.getPosition());
vecRet.push_back(objRet);
debug(vecRet[0].s);
debug(vecRet[1].s);
debug(vecRet[0].img.getTexture());
debug(vecRet[1].img.getTexture());
sf::RenderWindow window(sf::VideoMode(500,500), "Window", sf::Style::Close);
window.setFramerateLimit(120);
while (window.isOpen())
{
for (sf::Event event; window.pollEvent(event);) {
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(vecRet[0]);
window.draw(vecRet[1]);
window.draw(vecRet[0].img);
window.draw(vecRet[1].img);
window.display();
}
return EXIT_SUCCESS;
}
There are two problems I can not solve:
1) Even doing push_back of the two cars, only the last image prevails.
Apparently, push_back refers to a single RAM address for the image.
Then the result looks like this:
That is, the second image (car-black.png) is probably overlapping the address of the first image.
The curious thing is that this only happens with the Texture class. In the example, the program debug a string within the class and in this case there is no overlap:
vecRet[0].s=car-red.png
vecRet[1].s=car-black.png
However the Texture objects within the class vector are pointing to the same memory address:
vecRet[0].img.getTexture()=000000C57A5FF250
vecRet[1].img.getTexture()=000000C57A5FF250
How to solve this?
2) The second problem is that, for each vecRet.push_back(objRet), the following errors appear in the console:
An internal OpenGL call failed in Texture.cpp(98).
Expression:
glFlush()
Error description:
GL_INVALID_OPERATION
The specified operation is not allowed in the current state.
What is this?

Your first problem happens because you only instantiate a single car, but you load both images onto it. The second problem might be caused by the fact that push_back() copies the elements into the vector, resulting in the creation of four cars in total, rather than two.
Try this code:
vector<car> vecRet(2);
vecRet[0].imgInit("car-red.png");
vecRet[0].setSize(sf::Vector2f(150, 70));
vecRet[0].setFillColor(sf::Color::Yellow);
vecRet[1].imgInit("car-black.png");
vecRet[1].setPosition(sf::Vector2f(300, 300));
vecRet[1].img.setPosition(vecRet[1].getPosition());

Related

Access violation when writing to vector at runtime

I'm pretty new to C++ and just getting started with pointers and such. I'm making a simple game with SFML. I've made a vector "drawList" to store all the shapes in the game that will be rendered on screen. If I add the shapes to the vector before the main loop starts it works fine, however when I add objects at runtime I get an Access violation error on the following code:
for (size_t i = 0; i < drawList.size(); i++){
window.draw(*drawList[i]);
}
I think that the *drawlist[i] is an invalid pointer, however attempts to fix the issue so far have been unsuccessfull. The drawList vector and the method to add objects to it are setup like this in a header:
extern std::vector<const sf::Drawable*> drawList;
struct Globals {
void AddDrawable(const sf::Drawable &drawable);
};
and like this in the associated cpp:
std::vector<const sf::Drawable*> drawList;
void Globals::AddDrawable(const sf::Drawable & drawable){
drawList.push_back(&drawable);
}
I then try to add a shape to the vector in the constructor of a newly instatiated projectile class by calling the "AddDrawable" method and giving it the following method as parameter:
sf::RectangleShape& GetShape() { return shape; };
I feel like there is something really obvious going wrong with the references and pointers of things but so far I've not been able to figure it out. If anyone could suggest me ways to adress this issue it would be greatly appriciated. Thanks in advance!
EDIT:
I'll try to give some more context on Cris Luengo's suggestion, I have a main.cpp containing the main while loop. Before that while loop is initiated I instantiate a Player and a Projectile class. Inside the while loop I check if there is anything to update and draw in a forloop like so:
int main() {
Projectile bullet = Projectile(WINDOW_WIDTH /2.f, WINDOW_HEIGHT /2.f, 0.05f, 0.05f);
Player player = Player(WINDOW_WIDTH / 2.f, WINDOW_HEIGHT / 1.2f);
while (true) {
window.clear(Color::Black);
if (Keyboard::isKeyPressed(Keyboard::Key::Escape)) break;
for (size_t i = 0; i < updateList.size(); i++){
updateList[i]();
window.draw(*drawList.at(i));
}
window.display();
The updateList and drawList are both vectors that get filled from the constructors of the Player and the Projectile classes like so (This is identical for both the player and the projectile constructor respectively):
Projectile::Projectile(float mX, float mY, float velX, float velY){
velocity = sf::Vector2f(velX, velY);
GetShape().setPosition(mX, mY);
//other shape stuff
Globals globals;
updateIndex = globals.AddToUpdateList([this]() {Update(); });
globals.AddDrawable(GetShape());
}
As shown earlier, the GetShape() method is setup in the Player and Projectile headers like like this:
sf::RectangleShape& GetShape() { return shape; };
As it stands right now, this code works when I instantiate the objects to be added to the drawList before the while loop starts. If I read new data to it at runtime, when it is also being read, the program throws an access violation error in the forloop when the drawList is being accessed.
I use the same code when adding things to the drawList at runtime. I simply instantiate a new Projectile on a button press. The idea is that the constructor of the instantiated class adds the needed data to the lists (The updateList works fine)
Thank you in advance

C++ OOP LNK2001 ERROR

As the title suggests, I have an OOP error in C++, the LNK2001 unresolved externals error. Here is my code, where did I go wrong?
I'm using sfml to use the graphics in VS2015.
// OOPExample.hpp
#pragma once
#include <SFML\Graphics.hpp>
#include <SFML\System.hpp>
#ifndef OOPEX_H
#define OOPEX_H
class OOPExample{
public:
static sf::CircleShape shape;
static float rot;
static void draw();
static void rotate();
};
#endif // OOPEX_H
// OOPExample.cpp
#include "OOPExample.hpp"
#include <SFML\Graphics.hpp>
void OOPExample::rotate() {
OOPExample::rot += 0.1f;
return;
};
void OOPExample::draw() {
OOPExample::shape.setFillColor(sf::Color::Red);
OOPExample::shape.setRotation(rot);
return;
};
// Source.cpp
#include <SFML/Graphics.hpp>
#include "OOPExample.hpp"
int main()
{
sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
OOPExample oopexample();
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(oopexample().shape);
window.display();
}
return 0;
}
From what I've seen it looks like I need a definition of the methods declared in OOPExample.hpp, but I have those exact definitions in OOPExample.cpp. Am I instantiating the class incorrectly in Source.cpp?
To your question about the link errors. The comments highlight most of them... These are not OOP errors but rather link time errors when you build your project. I don't know if you have any experience with compiled system-level languages; but it would be a good idea to learn the basics of the compile-link cycle and what is expected by the linker when putting the final program together. A simple example of how to define a static member variable follows.
// class1.h
Class1
{
public:
private:
static float rotation;
};
// class1.cpp
#include "class1.h"
int Class1::rotation = 5.0f;
Note that int Class1::rotation = 5.0f; happens once at program initialisation.
I don't know if you are following some tutorial where they are creating this class like this, but you have a worrying amount of static members. This is an OOP problem. If you want to make many objects/instances of OOPExample you need to understand what static means. In the context of a class, when you apply the static keyword to a variable it means that all OOPExample objects will share that one variable. This makes static member variables good for default values and things like the number of a given class. You could have a static int OOPExample::count; to count the number of OOPExample objects that you have made. I will put that in an example later.
There may be many reasons for link errors, particularly missing definitions. PcAF highlighted an important one in the comments to your question. But you may also be missing the SFML libraries. I vaguely remember SFML tutorials including detailed instructions on how to link their libraries in your environment. In VS that will be somewhere in your project properties. You will obviously get similar errors if you declared something in the header that is not in the implementation (usually the cpp). This was the case with your static variable, but applies to functions as well.
Now there is a lot wrong with the three files you provided. I edited them to highlight some of the problems but it is far from perfect. I would not approach it in this way because sf::CircleShape is already an object-orientated entity. It has all the things you are trying to implement already implemented. Never over-abstract a problem (I also realised at some point that we were rotating a filled circle haha). You should really follow the advice to get a good textbook and start from the ground-up. SFML is a huge library that will distract you from understanding the fundamentals of C++. OOP is but one aspect of C++ and you need to embrace all C++ fundamentals to use OOP effectively. If you do this, you will have the most powerful abstraction mechanisms available (in my opinion).
My edits follow, but really, it is just a demonstration of how deep the rabbit hole goes (it gets much worse). How to instantiate OOPExample is shown in main.
// OOPExample.h
#ifndef OOPEX_H
#define OOPEX_H
// Only include what you need to. Users of this header should be exposed to as
// little SFML as possible.
#include <SFML/Graphics/CircleShape.hpp>
class OOPExample{
public:
// Parameterless constructor.
OOPExample(); // Note, this sets the rotation to the default rotation.
// One that takes a initial rotation.
OOPExample(float initial_rotation);
// Rotate 0.1f (by default) or by user specified amount.
void rotate(float rotation = 0.1f);
// window.draw() takes a Drawable as its first argument. Fortunately,
// CircleShape is a shape which in turn is a Drawable. Notice that we
// return by constant reference. Callers cannot edit our shape but they
// get a reference to the sf::CircleShape shape instance so they can read
// it.
// const, & (i.e. reference), pointers requires a deep understanding of
// object ownership, copying by value, by reference, and now of
// particular interest in C++11, moving.
const sf::CircleShape &getShape() const;
// You forgot to declare and define this.
void setRotation(float rotation);
// Set the default rotation for all objects created with the
// parameterless constructor.
static void setDefaultRotation(float rotation);
// The destructor.
virtual ~OOPExample();
private:
sf::CircleShape shape;
// sf::CircleShape already has a rotation with getters and setters.
// Don't over abstract!
// Our setRotation, rotate functions seem a bit unneccesary.
// float rotation;
// Defaults.
static sf::CircleShape default_circle;
static float default_rotation;
// Count example.
static int count;
};
#endif // OOPEX_H
// OOPExample.cpp
// Personally, and I know with most other C++ developers, I prefer my header's
// extension to be .h. .hpp usually identifies headers with
// implementations/definitions of classes in the header file itself (necessary
// in some circumstances).
#include "OOPExample.h"
//
// How to initialise static member variables. This happens once at the
// beginning of the program.
//
// All our circles have a default radius of 5.
sf::CircleShape OOPExample::default_circle = sf::CircleShape(5);
// And rotation of 0.
float OOPExample::default_rotation = 0;
int OOPExample::count = 0;
// The definition of the parameterless constructor.
OOPExample::OOPExample()
// A class initialiser list. How we build a new object.
: shape(default_circle) // We copy the default circle.
{
// Do other stuff to construct the object if you need to. For example:
shape.setFillColor(sf::Color::Red);
setRotation(default_rotation);
count++; // We just made another OOPEXample instance.
}
// The definition of a constructor that takes an initial rotation. I just
// realised we are rotating a circle!
OOPExample::OOPExample(float initial_rotation)
: shape(default_circle) // We copy the default circle.
{
// Do other stuff to construct the object if you need to. For example:
shape.setFillColor(sf::Color::Red);
// Notice: we used the user provided argument this time.
setRotation(initial_rotation);
count++; // We just made another OOPEXample instance.
}
void OOPExample::rotate(float rotation)
{
shape.rotate(rotation);
// return; // No need to specify a return for a void.
}
const sf::CircleShape &OOPExample::getShape() const
{
return shape;
}
void OOPExample::setRotation(float rotation)
{
shape.setRotation(rotation);
}
void OOPExample::setDefaultRotation(float rotation)
{
// OOPExample scoping is unnecessary.
OOPExample::default_rotation = rotation;
}
OOPExample::~OOPExample()
{
// Do things required for cleanup, i.e. deinit.
// One OOPExample just reached the end of its lifetime. Either it
// was deleted or reached the end of the
// scope (i.e. {}) it was created in.
count--;
}
// main.cpp
#include "OOPExample.h"
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
// Call the default, parameterless, constructor to instantiate an object
// of OOPExample.
OOPExample oopexample;
// Create another with a initial rotation of your choosing.
OOPExample another_obj(0.5f);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
// The instance object of OOPexample is referred to by oopexample.
// window.draw(oopexample().shape);
// This member is now private.
//window.draw(oopexample.shape);
window.draw(oopexample.getShape());
window.display();
}
return 0;
}

SFML texture not loading when encapsulating class member function is called from outside

tl/dr:I've moved a function call from inside a class to outside a class and the function stopped working.
I've run in to the most baffeling problem in the year or so I've been working with c++. I can't find anything to explain what is happening here but to be honest I have a hard time even formulating a SEO question.
the base operation here is rather simple,
create a sf::Texture and sf::Sprite object
Load a texture to the sf::Texture object
set texture of sf::Sprite to the texture object
display the sf::Sprite
all 4 steps went fine within one function, but because my goal was to build a game engine I started encapsulating it into larger classes.
I created a GameEngine class and let it handle step 4. this went well after some corrections.
then I created a GameObject class to handle the first three steps, all I had to do then as a 'user' of the framework was create the object and tell it to render, this also worked.
Then I hit a snag when I moved the functioncall for step 2. from the constructer of the object to outside of the object.
old situation:
class GameObject
{
ObjectType d_type;
GameEngine *d_engine;
sf::Texture d_texture;
sf::Sprite d_sprite;
bool isactive;
public:
GameObject(GameEngine *engine, ObjectType type);
void addtexture(std::string textpath);
void render();
and
GameObject::GameObject(GameEngine *engine, ObjectType type)
:
d_type(type),
d_engine(engine),
d_texture(),
d_sprite(),
isactive{false}
{
addtexture("textures//MenuBackGround.png"); //<- problematic line
d_sprite.setTexture(d_texture);
}
void GameObject::addtexture(std::string textpath)
{
if(!d_texture.loadFromFile(textpath))
{
cout << "couldn't load texture in\n";
} else
{
cout << "did load texture\n";
}
}
this works and I see the texture I created apear in the window. If I now create a class Loadingscreen:
class Loading_Screen : public Base_State
{
std::vector<GameObject> d_backgrounds;
public:
Loading_Screen(GameEngine *engine);
virtual ~Loading_Screen();
with implementation:
Loading_Screen::Loading_Screen(GameEngine *engine)
{
GameObject temp(engine, ObjectType::BACKGROUND);
d_backgrounds.push_back(temp);
temp.addtexture("textures//MenuBackGround.png");
}
I only see a blackscreen. but in both cases I get the message that the texture was loaded.
Assuming you're actually rendering d_backgrounds, I think the error is here:
Loading_Screen::Loading_Screen(GameEngine *engine)
{
GameObject temp(engine, ObjectType::BACKGROUND);
d_backgrounds.push_back(temp);
temp.addtexture("textures//MenuBackGround.png");
}
You are creating a GameObject object. Then you insert a copy of it into the container, and what you're trying to addtexture later is not the same object you inserted.
Try this:
Loading_Screen::Loading_Screen(GameEngine *engine)
{
GameObject temp(engine, ObjectType::BACKGROUND);
temp.addtexture("textures//MenuBackGround.png");
d_backgrounds.push_back(temp);
}
Looking at SFML api, Texture and Sprite have both proper copy constructors, so it should be fine this way.

SFML texture displaying as a white box

I have a texture and sprite in a base class that is being extended by another class, however when drawn, the sprite displays as a white box. I know this is something to do with the sprite losing it's link to the texture object, but I'm kind of new to C++, so I'm not really sure how it happened.
Here is the code (I've removed some of the irrelevant parts to cut down the size):
Pickup.h:
#ifndef PICKUPS_PICKUP_H
#define PICKUPS_PICKUP_H
#include <SFML\Graphics.hpp>
#include "..\Player.h"
namespace Pickups
{
class Pickup
{
private:
sf::Vector2f position;
sf::Texture texture;
sf::Sprite sprite;
public:
Pickup();
bool drop(float dt);
void draw(sf::RenderWindow* window);
void setTexture(sf::String name);
void setPos(sf::Vector2f position);
sf::Vector2f getPos();
void isColliding(Player* player);
virtual void onCollect(Player* player) = 0;
};
}
#endif
pickup.cpp:
#include "Pickup.h"
namespace Pickups
{
Pickup::Pickup()
{
}
void Pickup::draw(sf::RenderWindow* window)
{
window->draw(sprite);
}
void Pickup::setTexture(sf::String name)
{
if (!texture.loadFromFile("images/pickups/" + name + ".png"))
std::cout << "Error loading image: images/pickups/" + name.toAnsiString() + ".png" << std::endl;
else
sprite.setTexture(texture);
}
}
Health.h:
#ifndef PICKUPS_HEALTH_H
#define PICKUPS_HEALTH_H
#include "Pickup.h"
namespace Pickups
{
class Health : public Pickup
{
private:
int worth;
public:
Health(sf::Vector2f position, int worth);
void onCollect(Player* player);
};
}
#endif
health.cpp:
#include "Health.h"
namespace Pickups
{
Health::Health(sf::Vector2f position, int worth)
{
setTexture("health");
setPos(position);
this->worth = worth;
}
void Health::onCollect(Player* player)
{
player->addLives(worth);
}
}
(I don't know if this is part of the problem, but I might as well post it too)
I store the pickups in a vector like so:
std::vector<Pickups::Health> pickups;
A std::vector copies or moves the inserted elements, so as long as you have the default copy constructor or as long as you do not change this dirty a texture per element-style, (the elements just need to have one common texture object to actually point to, so you waste much much memory) the pointer that the sf::Sprite object holds to the texture gets invalid. To see why we need to think whats happens on insertion:
You setup a nice Pickupish object and add it to the vector which calls the copy-constructor. Lets say your nice object that you wanted to add is object A and the now added/copied object is B. Both have a sprite S and a texture T. Both textures are valid, but the problem is this: A's S points to A's T, so after copying it to B B's S points also to A's T! As I assume A is just temporary so it gets destructed, together with its texture, and there you have it, a nice white box.
You can solve this in some other dirty ways like making your own copy-constructor in Pickup like this:
Pickup::Pickup(const Pickup& other)
: position(other.position), texture(other.texture), sprite(other.sprite)
{ sprite.setTexture(texture); }
or by storing std::unique_ptr<Pickups::Health>'s and not just Pickups::Health's.
However a much better way you should use is some kind of Resourcemanager, which just stores all relevant textures, ideally one, a big tileset, because loading once but big is faster than loading multiple but small textures. You can write your own very simple manager or use some other e.g. the one from the great Thor library. To set a specific tile as texture for a Sprite just call sf::Sprite::setTextureRect.
I want to mention some additional improvements to your design. Let Pickup derive from sf::Drawable and define its pure virtual draw function, which you can make private. Thus your from Pickup deriving object doesn't need to know from any sf::RenderTarget and you can just do target.draw(myPickupObject).
There is no need to store the position, just let Pickup derive from sf::Transformable, too. You don't have to implement any functions, the only thing you need to do is applying the matrix to the sf::RenderStates object thats passed to draw.
Overall your draw function might look like this:
void Pickup::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
//'applying' transformation-matrix
states.transform *= getTransform();
target.draw(sprite, states);
}
So your Pickup has now only sf::Sprite as member and overall your header just needs to include SFML/Graphics/Sprite.hpp.
For avoid this type of problem I always declare my Texture as a pointer and deleting it in the destructor of the class. Like this your Texture will always exist whenever your object is not destroyed.
And it's always good to verify the loading of the image :
if (!texture.loadFromFile("images/pickups/health.png")){
//some error code
}
But it's not the problem here.

Texture going out of scope in SFML

Well, I'm trying to make a menu using SFML 2.1. I have a 'something.h' header file and two source files. For the buttons, I've created a texture file. Now, since I want all the menu buttons to have the same texture, I was trying to declare the texture globally. I tried a couple of ways to do this. I tried to declare it just before all the class declarations in something.h, but I found out that you can't use texture.loadFromFile("blahblah") without a function. SO, I decided to make a class for this, and the following is the code.
Something.h
#include<SFML/Graphics.hpp>
#include<iostream>
class Textureinitialize
{
public:
sf::Texture texture;
sf::Font font;
void loadtexture(const std::string& texturestring); //Specify file-name of texture
void loadfont(const std::string& fontstring); //Specify file-name of font
};
class Menubutton
{
public:
sf::Sprite menubuttonsprite;
sf::Text menubuttontext;
sf::Vector2i spritekaposition;
void loadthesprite(Textureinitialize obj1); //Load sprite from Texture and Text from font
void loadtexturepos(sf::IntRect rect1); //Load the sprite rectangle from the Texture
void spriteposition(sf::Vector2i originpos); //Specify position of button on the screen
void texttodisplay(std::string displaystring); //String to be displayed in button
void positionoftext(sf::Vector2i textpos,int textsize); //Set position and size of text to be displayed
};
This gave no error, but the menu button sprite does not display on the screen. I think the problem is with the loading of the texture. I looked around, and found that somehow the texture is going out of scope. Please could anyone help me?
EDIT:
I guess more code is the need of the hour. Here are the contents of the two source files I mentioned.
Something.cpp
#include "Menudata.h"
void Textureinitialize::loadtexture(const std::string& texturestring)
{
if(!texture.loadFromFile(texturestring))
std::cout<<"\nFailed to load textures";
}
void Textureinitialize::loadfont(const std::string& fontstring)
{
if(!font.loadFromFile(fontstring))
std::cout<<"\nFailed to load font";
}
void Menubutton::loadthesprite(Textureinitialize obj1)
{
menubuttonsprite.setTexture(obj1.texture);
menubuttontext.setFont(obj1.font);
}
void Menubutton::spriteposition(sf::Vector2i originpos)
{
spritekaposition.x=originpos.x;
spritekaposition.y=originpos.y;
menubuttonsprite.setPosition(originpos.x,originpos.y);
}
void Menubutton::loadtexturepos(sf::IntRect rect1)
{
menubuttonsprite.setTextureRect(rect1);
}
void Menubutton::texttodisplay(std::string displaystring)
{
menubuttontext.setString(displaystring);
}
void Menubutton::positionoftext(sf::Vector2i textpos,int textsize)
{
menubuttontext.setPosition(spritekaposition.x+textpos.x,spritekaposition.y+textpos.y);
menubuttontext.setCharacterSize(textsize);
menubuttontext.setColor(sf::Color::Red);
}
Main.cpp
#include "Menudata.h"
int main()
{
Textureinitialize a;
a.loadtexture("Menubutton.tga");
a.loadfont("arial.ttf");
Menubutton b;
b.loadthesprite(a);
b.loadtexturepos(sf::IntRect(0,0,80,48));
b.spriteposition(sf::Vector2i(50,50));
b.texttodisplay("Hello!");
b.positionoftext(sf::Vector2i(50,14),20);
sf::RenderWindow window(sf::VideoMode(200,200),"My Window");
while(window.isOpen())
{
sf::Event event;
while(window.pollEvent(event))
{
if(event.type==sf::Event::Closed)
window.close();
if(event.type==sf::Event::MouseButtonPressed)
{
b.loadtexturepos(sf::IntRect(0,48,80,48));
if(event.mouseButton.button==sf::Mouse::Left)
std::cout<<"\nHello!!!";
}
if(event.type==sf::Event::MouseButtonReleased)
b.loadtexturepos(sf::IntRect(0,0,80,48));
}
window.clear(sf::Color::Green);
window.draw(b.menubuttonsprite);
window.draw(b.menubuttontext);
window.display();
}
return 0;
}
The reason I thought the texture is going out of scope was that I read somewhere on Google that if you're getting a white rectangle instead of the image, you might have the said issue. Also, I just noticed that I couldn't see any text in the white box. I do have a function which displays text on the buttons in the class 'Menubutton'. I think the problem might be in the initialization of font. I hope what I've done in the class 'Textureinitialize' isn't wrong. I guess the problem might lie there.
As far as managing SFML resources goes, e.g. textures, I can only recommend this template:
https://github.com/LaurentGomila/SFML-Game-Development-Book/tree/master/02_Resources/Include/Book
This is a, in my opionion, simple way to access the texture whenever you need it to construct your buttons
P.S.: To improve readability of your code, I suggest using notations such as my_function or myFunction, instead of myfunction (all lowercase).