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

Author Topic: Odd problem with a Sprite or Image  (Read 4147 times)

0 Members and 2 Guests are viewing this topic.

Austech

  • Newbie
  • *
  • Posts: 23
    • View Profile
Odd problem with a Sprite or Image
« on: March 26, 2010, 12:55:06 am »
Okay, this has had me stumped for a good hour or two. And I can't seem to figure out why this is happening. I'm working on a game currently, and it involves vectors that hold sprites and things like that. Although, for some reason, the sprites are drawn to the window, and they're just white. They're the correct size, just no color. Obviously I didn't expect anyone to look at my whole game's source code and pick out a problem, so I made a mini program with fake classes that sort of simulate what happens in my game.

Code: [Select]

//TestClass.h
#pragma once
#include <SFML/Graphics.hpp>
#include "TestClassTwo.h"

class TestClass
{
public:

void Foo();
std::vector <sf::Sprite> Sprites;
private:
};

void TestClass::Foo()
{
TestClass2 T2;
T2.Img.LoadFromFile("SpriteSheet.png");
T2.Spr.SetImage(T2.Img);

Sprites.push_back(T2.Spr);
}


Code: [Select]

//TestClassTwo.h

#pragma once

#include <SFML/Graphics.hpp>

class TestClass2
{
public:
sf::Sprite Spr;
sf::Image Img;
private:
};


Code: [Select]

//main.cpp
#include "TestClass.h"
#include "TestClassTwo.h"

int main()
{
sf::RenderWindow Win;
Win.Create(sf::VideoMode(1000,800,32),"Test");
sf::Event Event;

TestClass T1;

T1.Foo();

while(Win.IsOpened())
{
while(Win.GetEvent(Event))
{
if(Event.Type == Event.Closed)
{
Win.Close();
}
}

Win.Clear(sf::Color(0,0,0));
Win.Draw(T1.Sprites[0]);
Win.Display();
}
}


As I said, these classes are short parts of the game that are most definitely causing the problems. I just can't figure out why. Huge thanks in advanced.

Austech

  • Newbie
  • *
  • Posts: 23
    • View Profile
Odd problem with a Sprite or Image
« Reply #1 on: March 26, 2010, 01:08:29 am »
Wow, sorry, I can't believe I put this in the wrong section, should I re-create one or will it be moved?

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
Odd problem with a Sprite or Image
« Reply #2 on: March 26, 2010, 01:18:16 am »
Memory slicing occurs. Test class 2 has member data for its image and sprite. However, when Test class 1 creates Test class 2, it goes out of scope and all that remains is the drawable sprite. You have to save the image to some place in Class 1 as well. You are only saving the sprite (to the vector)!
The image never enters the vector.

Austech

  • Newbie
  • *
  • Posts: 23
    • View Profile
Odd problem with a Sprite or Image
« Reply #3 on: March 26, 2010, 01:30:01 am »
This may sound pathetic of me, but I still don't understand completely. I tried even making the class like this:

Code: [Select]

class TestClass
{
public:

void Foo();
std::vector <TestClass2> Sprites;
private:
};

void TestClass::Foo()
{
TestClass2 T2;
T2.Img.LoadFromFile("SpriteSheet.png");
T2.Spr.SetImage(T2.Img);

Sprites.push_back(T2);
}


Yet it's still white. If I create a vector holding the TestClass2 (which holds the image and the sprite), how come when I try drawing it, it's still white?

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
Odd problem with a Sprite or Image
« Reply #4 on: March 26, 2010, 01:34:14 am »
Read this: http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c
Use pointers and allocate objects dynamically if you really want to do it this way (boost.ptr_vector is great for this).

Austech

  • Newbie
  • *
  • Posts: 23
    • View Profile
Odd problem with a Sprite or Image
« Reply #5 on: March 26, 2010, 02:35:25 am »
Okay, well I looked at what you said, and I also read up and refreshed my memory with Dynamic memory, but you seem more experienced than I am with this so I was wondering if I could check with you if this sounds right.

In the TestClass2, I made the image a pointer, and I made a constructor that made the image equal a new sf::Image()

Now when I create a TestClass2 and pass it in the vector, it's able to draw because the Image is able to be in a new memory address?

Sorry I'm not that "experienced" with memory and things like that. But would that be any were near correct?

Mindiell

  • Hero Member
  • *****
  • Posts: 1261
    • ICQ Messenger - 41484135
    • View Profile
Odd problem with a Sprite or Image
« Reply #6 on: March 26, 2010, 06:37:36 am »
Seems better.

If you do a local allocation of memory, the Image will be destroyed. So the Sprite will not be textured correctly (nothing to put on).
If you do a dynamic allocation, the Image will not be destroyed, thus the Sprite will have a texture. At the end, you will have to destroy, yourself, the Image.

What I could suggest to you is having a class which can manage all the Images (textures) of your game, and a class using Sprite. Because if you have 100 Sprites using the same Image (texture), with your model, you are going to load 100 times the same Image for nothing more than use a lot of memory.

In the Miscellaneous part of the "Source codes" wiki, you can find some ResourcesManager
Mindiell
----

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
Odd problem with a Sprite or Image
« Reply #7 on: March 26, 2010, 12:00:02 pm »
I suggest you become familiar with Boost.Ptr_Container: http://www.boost.org/doc/libs/1_42_0/libs/ptr_container/doc/ptr_container.html which is great for this stuff.
For instance, consider the following way to store images and sprites using ptr_vector:
Code: [Select]
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/foreach.hpp>
boost::ptr_vector<sf::Image> MyImages;
boost::ptr_vector<sf::Sprite> MySprites;

MyImages.push_back(new sf::Image("lol.png"));
MySprites.push_back(new sf::Sprite(MyImages.back()));

BOOST_FOREACH(sf::Sprite& CurrentSprite, MySprites)
    RenderWindow.Draw(CurrentSprite);


You could easily put these into a class :D. You might also want to use boost::ptr_map to store images by their string. That is basically a 2-line memory manager for you right there. The pointers are owned by the ptr_container and thus everything is safe.