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

Author Topic: Sprite rendering as white box  (Read 15555 times)

0 Members and 1 Guest are viewing this topic.

legacyblade

  • Newbie
  • *
  • Posts: 25
    • View Profile
Sprite rendering as white box
« on: August 24, 2012, 10:30:10 pm »
I know this question has been asked before. But I thought I tried the common solution and it didn't work. I did my research, lol.

I have created a class that will handle sprites. Once implemented, it'll be used to animate sprite-sheets. (in case you're wondering why I need a class that stores a sprite). I am storing both the sprite and it's texture as variables, and I'm using a function to access the stored sprite.

Here's gameSprite.h
#ifndef _GAMESPRITE_H
#define _GAMESPRITE_H

#include <SFML/Graphics.hpp>

#include <iostream>
#include <vector>
#include <string>

class gameSprite
{
public:
         gameSprite(std::string spriteSheet, int columns = 1, int rows = 1, int x = 0, int y = 0);
         sf::Sprite getSpritesheet();

private:
         sf::Sprite sprite;
         sf::Texture texture;
};

#endif
 

Here's gameSprite.cpp
#include <SFML/Graphics.hpp>

#include <string>

#include <iostream>

#include "gameSprite.h"

gameSprite::gameSprite(std::string spriteSheet, int columns, int rows, int x, int y)
{
        // temporarily hard coding the texture to be loaded for testing purposes
        texture.loadFromFile("img/MrZOMG.png");
        sprite.setTexture(texture);
}

sf::Sprite gameSprite::getSpritesheet()
{
        return sprite;
}
 

and here's the bit of code in my main loop where I try to draw the sprite

graphics.gameWindow.clear(sf::Color(0,255,255));
graphics.gameWindow.draw( (sprites[0]).getSpritesheet() );
graphics.gameWindow.display();
 


sprites is a vector containing instances of gameSprite. I'm hardcoding which one to draw for testing purposes.

I know both my posts have been asking for help. I'm sorry about that. Thank you so much for reading this, and any help or direction you can give would be great. (meanwhile, I'm going to try and make a quick and dirty workaround that'll re-load the texture over the sprite whenever the sprite is called up. I hope that's not the only option, as that sounds like it'd take more memory than just loading the texture once)

(UGH! I'm so used to hitting f5 to compile that I accidentally hit f5 when I wanted to post and it refreshed the page. So I had to write this twice)

-edit-

More code was asked for, so here's the code of my game loop.

game.h
#ifndef _GAME_H
#define _GAME_H

#include <vector>

#include "graphic.h"
#include "input.h"
#include "setting.h"
#include "gameSprite.h"


class game
{
public:
         game();
        void gameLoop();

        graphic graphics;
        std::vector<gameSprite> sprites;
        std::vector<input> inputs;
        setting settings;
};

#endif
 

game.cpp
#include <vector>

#include <iostream>

#include "game.h"
#include "global.h"
#include <SFML/Graphics.hpp>

game::game()
{
        inputs.push_back(input(1));
        sprites.push_back(gameSprite("img/MrZOMG.png"));
}

void game::gameLoop()
{
        while(graphics.gameWindow.isOpen())
        {
                for (std::size_t i=0; i<inputs.size(); i++) {
                        (inputs.at(i)).update();
                }
                sf::Event Event;
                while(graphics.gameWindow.pollEvent(Event))
                {
                        switch(Event.type)
                        {
                        case sf::Event::Closed:
                                std::cout << "The window was closed." << std::endl;
                                graphics.gameWindow.close();
                                break;

                        default:
                                break;

                        }

                        graphics.gameWindow.clear(sf::Color(0,255,255));
                        graphics.gameWindow.draw( (sprites[0]).getSpritesheet() );
                        graphics.gameWindow.display();

                }
        }
        std::cout << "Loop has ended." << std::endl;
}
 
« Last Edit: August 24, 2012, 10:52:17 pm by legacyblade »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Sprite rendering as white box
« Reply #1 on: August 24, 2012, 10:48:52 pm »
Unfortunatly you don't provide enough code we can go about.
The problem basically occures when the sprite loses the reference to the texture or the texture gets released although the sprite still uses it.
For beginners this mostly happens when they declare the texture in one scope and try to use it in another one. If one is using textures as a member variable of a class and then copies that class without having your own copy constructor defined it can also happen that the texture gets released.
So with the provided code we can't really tell you when things go wrong, please always include a minimal but complete example. ;)

The brackets around your sprites array isn't really needed and just makes you code look strange.
Another hint, return the sprite as reference rather than by value (i.e. const sf::Sprite& getSpritesheet()).

I know both my posts have been asking for help. I'm sorry about that.
Well that's what this forum is mostly about, asking questions, receiving help or helping others. ;)

(UGH! I'm so used to hitting f5 to compile that I accidentally hit f5 when I wanted to post and it refreshed the page. So I had to write this twice)
Chrome FTW, it (mostly) saves your entries etc. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

legacyblade

  • Newbie
  • *
  • Posts: 25
    • View Profile
Re: Sprite rendering as white box
« Reply #2 on: August 24, 2012, 11:00:46 pm »
Unfortunatly you don't provide enough code we can go about.
The problem basically occures when the sprite loses the reference to the texture or the texture gets released although the sprite still uses it.
For beginners this mostly happens when they declare the texture in one scope and try to use it in another one. If one is using textures as a member variable of a class and then copies that class without having your own copy constructor defined it can also happen that the texture gets released.
So with the provided code we can't really tell you when things go wrong, please always include a minimal but complete example. ;)

I was saving the texture and sprite as a private variable. So I thought a function that outputs the sprite would be enough to keep the texture in proper scope so the program could access it. I've currently got the thing working by changing my getSpritesheet function (also renamed it to getSprite, since I added spritesheet as a variable that holds the location of the file to be looked up). Now it does this

sf::Sprite gameSprite::getSprite()
{
        texture.loadFromFile(spriteSheet);
        sprite.setTexture(texture);

        return sprite;
}
 

and that works. But I think there's a better way to do it, because having to reload the image into memory EVERY TIME I render the sprite seems like a poor way to do it x.x if I leave off the texture.loadFromFile bit, it doesn't even give me a white box. Just nothingness o.o But it works for now, I'm just hoping for a better way around it

The brackets around your sprites array isn't really needed and just makes you code look strange.
Another hint, return the sprite as reference rather than by value (i.e. const sf::Sprite& getSpritesheet()).

That's just a bad habit I've developed over the past couple days. I've been using a lot of vectors, and sometimes it gets mad if you don't have parenthesis around things (vector(0).first.size()) will make an errror, however (vector(0).first).size() won't ) . I'm going to clean all the unnecessary parenthesis up when I clean up my code later in the project.

Well that's what this forum is mostly about, asking questions, receiving help or helping others. ;)

Glad to hear it :) I'm used to RPGMaker forums. They usually don't like people who only use the question boards when they first join.

Chrome FTW, it (mostly) saves your entries etc. ;)
Using chrome. It didn't save it :P But chrome doesn't always do what it's supposed to over on this machine.