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

Author Topic: window.draw(*gameobject->getSprite()) texture is white, why?  (Read 3986 times)

0 Members and 1 Guest are viewing this topic.

Putarda

  • Jr. Member
  • **
  • Posts: 56
    • View Profile
window.draw(*gameobject->getSprite()) texture is white, why?
« on: August 24, 2016, 03:28:04 pm »
Hello, so i'm messing with basic sfml engine about 1 week and i'm tired of it. Can anyone just help me to finish it? I just need one small step to finish it. So here is my problem:
GameObject::GameObject* gameobject = GameObject::getGameObject("player_gameobject");
window.draw(*gameobject->getSprite());
When i draw it texture is white.
« Last Edit: August 24, 2016, 03:29:58 pm by Putarda »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: window.draw(*gameobject->getSprite()) texture is white, why?
« Reply #1 on: August 24, 2016, 04:01:26 pm »
Did you read The White Square Problem paragraph in the sprite tutorial?
If so, do you understand issue?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Putarda

  • Jr. Member
  • **
  • Posts: 56
    • View Profile
Re: window.draw(*gameobject->getSprite()) texture is white, why?
« Reply #2 on: August 24, 2016, 04:56:54 pm »
Okay, so how do i fix this?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
AW: window.draw(*gameobject->getSprite()) texture is white, why?
« Reply #3 on: August 24, 2016, 05:23:40 pm »
Don't let the texture go out of scope as long as the sprite exists.
Don't let the texture being moved in memory (e.g. don't use a std::vector as container).
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Putarda

  • Jr. Member
  • **
  • Posts: 56
    • View Profile
Re: window.draw(*gameobject->getSprite()) texture is white, why?
« Reply #4 on: August 26, 2016, 09:15:37 pm »
Can you please tell me where is my mistake  :-\?
GameObject.cpp:
#include "GameObject.h"
#include <unordered_map>

namespace GameObject {

        std::unordered_map<std::string, GameObject> gameobjects;

        GameObject::GameObject() {

                name = "gameobject";

                sprite = sf::Sprite();

        }

        GameObject::GameObject(std::string gameobject_name, sf::Sprite gameobject_sprite, sf::Texture sprite_texture, int gameobject_position_x, int gameobject_position_y) {

                name = gameobject_name;

                sprite = gameobject_sprite;

                sprite.setTexture(sprite_texture);

                sprite.setPosition(gameobject_position_x, gameobject_position_y);

        }

        void GameObject::setName(std::string gameobject_name) {

                name = gameobject_name;

        }

        void GameObject::setSprite(sf::Sprite gameobject_sprite) {

                sprite = gameobject_sprite;

        }

        void GameObject::setTexture(sf::Texture gameobject_texture) {

                sprite.setTexture(gameobject_texture);

        }

        std::string* GameObject::getName() {

                return &name;
        }

        sf::Sprite* GameObject::getSprite() {

                return &sprite;
        }

        void addGameObject(GameObject gameobject) {

                gameobjects[*gameobject.getName()] = gameobject;

        }

        void removeGameObject(std::string gameobject_name) {

                gameobjects.erase(gameobject_name);

        }

        GameObject* getGameObject(std::string gameobject_name) {

                return &gameobjects[gameobject_name];
        }

        //std::vector<GameObject*> getGameObjects() {

        //      std::vector<GameObject*> gameobjects_c2;

        //      gameobjects_c2.reserve(gameobjects.size());

        //      for (auto gameobject : gameobjects) {

        //              gameobjects_c2.insert(gameobjects_c2.begin(), &gameobject.second);

        //      }

        //      return gameobjects_c2;
        //}

}
 
GameObject.h:
#include <SFML\Graphics.hpp>

namespace GameObject {

        class GameObject {

        private:

                std::string name;

                sf::Sprite sprite;

        public:

                GameObject();

                GameObject(std::string gameobject_name, sf::Sprite gameobject_sprite, sf::Texture sprite_texture, int gameobject_position_x, int gameobject_position_y);

                void setName(std::string gameobject_name);

                void setSprite(sf::Sprite gameobject_sprite);

                void setTexture(sf::Texture gameobject_texture);

                std::string* getName();

                sf::Sprite* getSprite();

        };

        void addGameObject(GameObject gameobject);

        void removeGameObject(std::string gameobject_name);

        GameObject* getGameObject(std::string gameobject_name);

        /*std::vector<GameObject*> getGameObjects();*/

}
 
Graphics.cpp:
#include <SFML\Graphics.hpp>
#include "Game.h"
#include "GameObject.h"
#include <iostream>

namespace Graphics {

        sf::RenderWindow window;

        void openWindow() {

                window.create(sf::VideoMode(800, 800), Game::getGameName());
                window.setVerticalSyncEnabled(true);

                while (window.isOpen()) {

                        sf::Event event;

                        while (window.pollEvent(event)) {

                                switch (event.type) {

                                case sf::Event::Closed:

                                        Game::closeGame();

                                        break;
                                }

                        }

                        window.clear();

                        GameObject::GameObject* gameobject = GameObject::getGameObject("player_gameobject");

                        window.draw(*gameobject->getSprite());

                        window.display();

                        //for (i = 0; i<drawTable.size(); i++)
                        //{
                        //      m_app->Draw(*drawTable[i]); //Here is the line causing the crash !
                        //}
                        //i = 0;

                }

        }

        void closeWindow() {

                window.close();

        }

}
 
Graphics.h:
#include <SFML\Graphics.hpp>

namespace Graphics {

        void openWindow();

        void closeWindow();

}
 

drako0812

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Personal Github Page
Re: window.draw(*gameobject->getSprite()) texture is white, why?
« Reply #5 on: August 27, 2016, 06:10:33 am »
I think the problem is your GameObject::setTexture method. You are passing the sf::Texture by value which means that particular instance will be destroyed as soon as that method returns.  You need to pass a reference or pointer and keep that reference or pointer alive somewhere else.

So a quick example:

In GameObject.h

// Rest of Game Object Declaration
void setTexture(const sf::Texture & gameobject_texture);
// Rest of Game Object Declaration

In GameObject.cpp

// Rest of Game Object Definition
// Basically the same as before
void GameObject::setTexture(const sf::Texture & gameobject_texture) {
    sprite.setTexture(gameobject_texture);
}
// Rest of Game Object Definition

In file where you set the texture:

// Rest of Code
sf::Texture texture; // IMPORTANT: Make sure texture outlives the GameObject
// Initialize the texture somehow
GameObject::GameObject* gameobject = GameObject::getGameObject("player_gameobject");
gameobject->setTexture(texture);
// Rest of Code

-- OR --

If you have C++11 or better compatibility (At least I think this should work)

// Rest of Code
std::shared_ptr<sf::Texture> texture = std::make_shared(new Texture()); // Now you can store the pointer somewhere else
// Initialize the texture somehow
GameObject::GameObject* gameobject = GameObject::getGameObject("player_gameobject");
gameobject->setTexture(*texture);
// Rest of Code

You could also use
std::unique_ptr<sf::Texture>
which enforces stricter ownership rules.

Putarda

  • Jr. Member
  • **
  • Posts: 56
    • View Profile
Re: window.draw(*gameobject->getSprite()) texture is white, why?
« Reply #6 on: August 27, 2016, 12:47:55 pm »
Thank you very much!

Putarda

  • Jr. Member
  • **
  • Posts: 56
    • View Profile
Re: window.draw(*gameobject->getSprite()) texture is white, why?
« Reply #7 on: August 28, 2016, 12:13:54 pm »
Not working... i tried everything  :-\. Here is rest of my code:
Game.cpp:
#include "Game.h"
#include "Graphics.h"
#include <iostream> //to remove
#include "GameObject.h"

namespace Game {

        const std::string game_name = "Game";

        bool game_opened = false;

        bool game_running = false;

        sf::Thread updategame_thread(&updateGame);

        void openGame() {

                if (game_opened) return;

                loadResources();

                startGame();

                game_opened = true;

                Graphics::openWindow();

        }

        void closeGame() {

                if (game_opened == false) return;

                stopGame();

                game_opened = false;

                Graphics::closeWindow();

        }

        void loadResources() {

                sf::Texture player_texture;

                player_texture.loadFromFile("C:/Users/User/Desktop/RANDOM ITEMS/BI logo.png");

                GameObject::GameObject gameobject("test", sf::Sprite(), player_texture); //create go

                GameObject::addGameObject(gameobject);

        }
GameObject.cpp:
#include <SFML\Graphics.hpp>
#include <string>
#include "GameObject.h"

namespace GameObject {

        std::unordered_map<std::string, GameObject> gameobjects;

        GameObject::GameObject() {

                name = "gameobject";

                sprite = sf::Sprite();

                texture = sf::Texture();

                sprite.setTexture(texture);

        }

        GameObject::GameObject(std::string gameobject_name, sf::Sprite gameobject_sprite, sf::Texture gameobject_texture) {

                name = gameobject_name;

                sprite = gameobject_sprite;

                texture = gameobject_texture;

                sprite.setTexture(texture);

        }

        void addGameObject(GameObject gameobject) {

                gameobjects[*gameobject.getName()] = gameobject;

        }

        GameObject* getGameObject(std::string gameobject_name) {

                return &gameobjects[gameobject_name];
        }

        std::string* GameObject::getName() {

                return &name;
        }

        sf::Sprite* GameObject::getSprite() {

                return &sprite;
        }

        sf::Texture* GameObject::getTexture() {

                return &texture;
        }

}
 
And Graphics.cpp:
#include <SFML\Graphics.hpp>
#include "Game.h"
#include "GameObject.h"

namespace Graphics {

        sf::RenderWindow window;

        void openWindow() {

                window.create(sf::VideoMode(800, 800), *Game::getGameName());
                window.setVerticalSyncEnabled(true);

                while (window.isOpen()) {

                        sf::Event event;

                        while (window.pollEvent(event)) {

                                switch (event.type) {

                                case sf::Event::Closed:

                                        Game::closeGame();

                                        break;
                                }

                        }

                        window.clear();

                        GameObject::GameObject* gameobject = GameObject::getGameObject("test");

                        window.draw(*gameobject->getSprite()); //and i got white box...

                        window.display();

                }

        }
 
Btw i just started with c++, i came from java. So i think that's the reason why i have problem with pointers...

Mr_Blame

  • Full Member
  • ***
  • Posts: 192
    • View Profile
    • Email
Re: window.draw(*gameobject->getSprite()) texture is white, why?
« Reply #8 on: August 28, 2016, 02:52:17 pm »
What about the corrected Object.h

Putarda

  • Jr. Member
  • **
  • Posts: 56
    • View Profile
Re: window.draw(*gameobject->getSprite()) texture is white, why?
« Reply #9 on: August 28, 2016, 04:22:22 pm »
I don't know what you mean?