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

Author Topic: Error displaying, pointer to Sprite  (Read 6193 times)

0 Members and 1 Guest are viewing this topic.

Xeshi

  • Newbie
  • *
  • Posts: 8
    • View Profile
Error displaying, pointer to Sprite
« on: March 21, 2011, 07:35:58 am »
Hi,
sorry for my English, I use google translate to translate.

I have problem with pointer to Sprite. I use dynamic memory to create new obiekt Sprite. Unfortunately, show me the white rectangle instead of my picture. Picture is certainly ok. This is my code:
Code: [Select]


        if(! iBall.LoadFromFile("obrazek.bmp") )
        {
                std::cout <<"Blad ladowania bitmapy pilki" <<std::endl;
        }else
        {
                std::cout <<"Zaladowano poprawnie bitmape pilki" <<std::endl;
        }
        iBall.CreateMaskFromColor( sf::Color::Black, 255 );
        //sf::Sprite sBall;
        pBall = new sf::Sprite;
        //pBall->SetColor(sf::Color::Green);
        pBall->SetImage( iBall );
        pBall->SetPosition(xP, yP);
        pBall->SetScale(1.0f, 1.0f);
        App::pApp->Draw( *pBall );
 

Please Help me.[/code]

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Error displaying, pointer to Sprite
« Reply #1 on: March 21, 2011, 10:12:51 am »
Please always try to provide a minimal example to reproduce your problem. Whereas it already seems to be rather minimalistic, you have a call to "App::pApp" and we have to guess how your code structure looks like. ;)

Here's a minimal example you can use to test if sprites with images get displayed correctly at all:

Code: [Select]
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>

int main() {
sf::RenderWindow window( sf::VideoMode( 800, 600, 16 ), "Test" );

sf::Image image;
image.LoadFromFile( "obrazek.bmp" );

sf::Sprite sprite( image );

window.Clear();
window.Draw( sprite );
window.Display();

sf::Sleep( 3.f );
return 0;
}


If that works, try to add CreateMaskFromColor() etc. (hopefully the code above is okay, it's untested)

P.S.: Google Translator does a good job nowadays. ;)

Xeshi

  • Newbie
  • *
  • Posts: 8
    • View Profile
Error displaying, pointer to Sprite
« Reply #2 on: March 21, 2011, 10:50:15 am »
Quote from: "Tank"
Please always try to provide a minimal example to reproduce your problem. Whereas it already seems to be rather minimalistic, you have a call to "App::pApp" and we have to guess how your code structure looks like. ;)

Here's a minimal example you can use to test if sprites with images get displayed correctly at all:

Code: [Select]
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>

int main() {
sf::RenderWindow window( sf::VideoMode( 800, 600, 16 ), "Test" );

sf::Image image;
image.LoadFromFile( "obrazek.bmp" );

sf::Sprite sprite( image );

window.Clear();
window.Draw( sprite );
window.Display();

sf::Sleep( 3.f );
return 0;
}


If that works, try to add CreateMaskFromColor() etc. (hopefully the code above is okay, it's untested)

P.S.: Google Translator does a good job nowadays. ;)


This example works well. Only, if I use pointer to Sprite displaying error.
The code to create pointer for the window.
Code: [Select]

App::App(void)
{
pApp= new sf::RenderWindow;
pApp->Create(sf::VideoMode(800,600, 32), "okno");
//pApp->Close();

}

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Error displaying, pointer to Sprite
« Reply #3 on: March 21, 2011, 10:53:58 am »
The pointer itself isn't the problem. Again I looked at your code, and there's "iBall", which seems to be put on stack. Are you sure the variable iBall is still there when you're drawing your sprite?

sf::Sprite only holds a reference to sf::Image and does not copy it. And since C++ doesn't have reference counting, you may get problems here.

Xeshi

  • Newbie
  • *
  • Posts: 8
    • View Profile
Error displaying, pointer to Sprite
« Reply #4 on: March 21, 2011, 11:37:11 am »
Quote from: "Tank"
The pointer itself isn't the problem. Again I looked at your code, and there's "iBall", which seems to be put on stack. Are you sure the variable iBall is still there when you're drawing your sprite?

sf::Sprite only holds a reference to sf::Image and does not copy it. And since C++ doesn't have reference counting, you may get problems here.

"iBall" is normaln var of class Image. It is certainly.

Do you give all the code?

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Error displaying, pointer to Sprite
« Reply #5 on: March 21, 2011, 11:40:45 am »
Quote
Do you give all the code?

Would be helpful to see more than your snippets, yes.

Xeshi

  • Newbie
  • *
  • Posts: 8
    • View Profile
Error displaying, pointer to Sprite
« Reply #6 on: March 21, 2011, 11:51:00 am »
Quote from: "Tank"
Quote
Do you give all the code?

Would be helpful to see more than your snippets, yes.

App.cpp
Code: [Select]
#include "App.hpp"
#include "Ball.hpp"
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <iostream>


sf::RenderWindow* App::pApp;
App::App(void)
{
pApp= new sf::RenderWindow;
pApp->Create(sf::VideoMode(800,600, 32), "okno");
//pApp->Close();

}
App::~App(void)
{
delete pApp;
std::cout<<"Wywoładno destruktor klasy App";
}
void App::ServiceEvent()
{
sf::Event Event;
while( pApp->GetEvent(Event) )
{
if( Event.Key.Code == sf::Key::Escape || Event.Type == sf::Event::Closed) { pApp->Close(); }
if( Event.Key.Code == sf::Key::Right) { /*przesun platforme w prawo */}

}
}
void App::Run()
{
Ball Ball(20.0f, 20.0f);
while( pApp->IsOpened() )
{
pApp->Display();
pApp->Clear();
App::ServiceEvent();
Ball.Update();
}
}

App.hpp
Code: [Select]

#pragma once
#include <SFML/Graphics.hpp>
class App
{
public:
App(void);
~App(void);
void ServiceEvent();
void Run();
//static float ElapsedTime;
static sf::RenderWindow *pApp; //wskaźnik na okno
};


Ball.hpp
Code: [Select]

#pragma once
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include "App.hpp"
class Ball
{
public:
Ball(float x, float y); //x, y pozycja poczatkowa pilki
//~Ball(void);
void Update();
private:
sf::Sprite *pBall; //wskaźnik na obiekt piłki
float x; //pozycja na osi x
float y; //pozycja na osi y
float vy; //predkosc na osi y
float vx; //predkosc na osi x
int width; //Wymiary okna
int height; //do wyswietlania

};


Ball.cpp
Code: [Select]

#include "Ball.hpp"
#include "App.hpp"
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <iostream>



//Ball::~Ball(void){}
//konstruktor, zaladowanie obrazu pilki 32x32px
Ball::Ball(float xP, float yP)
{
std::cout <<"Wywołano: Konstruktor Ball" <<std::endl;
sf::Image iBall;
if(! iBall.LoadFromFile("pilka.bmp") )
{
std::cout <<"Blad ladowania bitmapy pilki" <<std::endl;
}else
{
std::cout <<"Zaladowano poprawnie bitmape pilki" <<std::endl;
}
iBall.CreateMaskFromColor( sf::Color::Black, 255 );
//sf::Sprite sBall;
pBall = new sf::Sprite;
//pBall->SetColor(sf::Color::Green);
pBall->SetImage( iBall );
pBall->SetPosition(xP, yP);
pBall->SetScale(1.0f, 1.0f);
x= xP;
y= yP;
vx= 100;
vy= 100;
width= App::pApp->GetWidth();
height= App::pApp->GetHeight();
}
//Koniec konstruktora

void Ball::Update()
{
float ElapsedTime= App::pApp->GetFrameTime();
// std::cout<<"Funkcja update wywołana" <<std::endl;
x+= vx * ElapsedTime;
y+= vy * ElapsedTime;
pBall->SetPosition(x, y);
//int width= App::pApp->GetWidth();
//int height= App::pApp->GetHeight();

if( x >= (width-32) )
{
x= width-32;
vx*= -1;
}
if( x<= 0 )
{
vx*= -1;
x=0;
}
if( y>= (height-32))
{
y= height-32;
vy*= -1;
}
if( y <= 0 )
{
vy*= -1;
y= 0;
}
App::pApp->Draw( *pBall );
}




Main.cpp
Code: [Select]

//Plik glowny pileczki :) Made by KeeL
#include <iostream>
#include <SFML/Graphics.hpp>
#include "App.hpp"
int main()
{
std::cout<<"Sterowanie strzałkami";
//App app;
App *pPoint= new App;
pPoint->Run();
//pPoint-> ~App();
return 0;
}

devlin

  • Full Member
  • ***
  • Posts: 128
    • View Profile
Error displaying, pointer to Sprite
« Reply #7 on: March 21, 2011, 12:35:42 pm »
Ugh - apart from abusing pointers everywhere even when not needed - and a static renderwindow, your image file goes out of scope when leaving the Ball::Ball constructor. Thus, the image is no longer available when you're trying to draw the sprite.

Please read the documentation here:
http://www.sfml-dev.org/documentation/2.0/classsf_1_1Sprite.htm

Especially this part:
Quote
It is important to note that the sf::Sprite instance doesn't copy the image that it uses, it only keeps a reference to it. Thus, a sf::Image must not be destructed while it is used by a sf::Sprite (i.e. never write a function that uses a local sf::Image instance for creating a sprite).

Xeshi

  • Newbie
  • *
  • Posts: 8
    • View Profile
Error displaying, pointer to Sprite
« Reply #8 on: March 21, 2011, 12:40:36 pm »
Quote from: "devlin"
Ugh - apart from abusing pointers everywhere even when not needed - and a static renderwindow, your image file goes out of scope when leaving the Ball::Ball constructor. Thus, the image is no longer available when you're trying to draw the sprite.

Please read the documentation here:
http://www.sfml-dev.org/documentation/2.0/classsf_1_1Sprite.htm

Especially this part:
Quote
It is important to note that the sf::Sprite instance doesn't copy the image that it uses, it only keeps a reference to it. Thus, a sf::Image must not be destructed while it is used by a sf::Sprite (i.e. never write a function that uses a local sf::Image instance for creating a sprite).


Thanks For Help.
How is the easiest way to fix?

This is my first advanced program. Just learning C++ with the library SFML.

devlin

  • Full Member
  • ***
  • Posts: 128
    • View Profile
Error displaying, pointer to Sprite
« Reply #9 on: March 21, 2011, 01:06:45 pm »
The easiest way for you would most likely be to include "iBall" inside the Ball class as a member of that class, instead of declaring it inside the constructor.

And please, don't make it a pointer like everything else. ;)

Like this:

Code: [Select]

class Ball
{
/* removed for easier reading */
private:
     sf::Image iBall;
};

Ball::Ball(float xP, float yP)
{
   if(! iBall.LoadFromFile("pilka.bmp") )
   {
/* removed for easier reading */

Xeshi

  • Newbie
  • *
  • Posts: 8
    • View Profile
Error displaying, pointer to Sprite
« Reply #10 on: March 21, 2011, 01:21:38 pm »
Quote from: "devlin"
The easiest way for you would most likely be to include "iBall" inside the Ball class as a member of that class, instead of declaring it inside the constructor.

And please, don't make it a pointer like everything else. ;)

Like this:

Code: [Select]

class Ball
{
/* removed for easier reading */
private:
     sf::Image iBall;
};

Ball::Ball(float xP, float yP)
{
   if(! iBall.LoadFromFile("pilka.bmp") )
   {
/* removed for easier reading */


So Image obiekt is to be in the class, and his statement is to be in the constructor?

I realized my mistake. By creating an image object in the constructor it was local, and after exiting the constructor was removed, so show me a white rectangle.

devlin

  • Full Member
  • ***
  • Posts: 128
    • View Profile
Error displaying, pointer to Sprite
« Reply #11 on: March 21, 2011, 01:45:20 pm »
That is correct.

It's the way which means the least changes for you.

Xeshi

  • Newbie
  • *
  • Posts: 8
    • View Profile
Error displaying, pointer to Sprite
« Reply #12 on: March 24, 2011, 05:31:25 pm »
Quote from: "devlin"
That is correct.

It's the way which means the least changes for you.


Sorry that such a long time, but I did not have access to a computer at the moment. After the change does not display anything to me, I have a black screen. I changed only this entry which I have said.

EDIT
I tried to use the index at all when creating a Sprite, but that does not display anything. Stowrzyłem simplest example code. Image Creation, loading the file, create a Sprite and view it using the index and, unfortunately, does not show it. By using simple variable is all about

kalgon

  • Newbie
  • *
  • Posts: 37
    • View Profile
Error displaying, pointer to Sprite
« Reply #13 on: March 24, 2011, 10:54:27 pm »
show your new code if help is needed.


just comments :

Code: [Select]
int main()
{
   std::cout<<"Sterowanie strzałkami";
   //App app;
   App *pPoint= new App;
   pPoint->Run();
   //pPoint-> ~App();
   return 0;
}


 :shock:

Code: [Select]
int main()
{
   std::cout<<"Sterowanie strzałkami";
   App app;
   app.Run();
   return 0;
}


or

Code: [Select]
int main()
{
   App *app=new App;
   app->Run();
   delete app;
   return 0;
}


are better

and you can do simple : inherit the class App from RenderWindow and the class Ball from Sprite

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Error displaying, pointer to Sprite
« Reply #14 on: March 25, 2011, 08:37:49 am »
Go for the first version. Never ever use the heap when there's not a good reason to do so!